diff --git a/aurorastation.dme b/aurorastation.dme
index eeaacdb4474..eb012b3dff0 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -1108,7 +1108,7 @@
#include "code\game\objects\structures\banner.dm"
#include "code\game\objects\structures\barsign.dm"
#include "code\game\objects\structures\bedsheet_bin.dm"
-#include "code\game\objects\structures\coathanger.dm"
+#include "code\game\objects\structures\coatrack.dm"
#include "code\game\objects\structures\crystals.dm"
#include "code\game\objects\structures\curtains.dm"
#include "code\game\objects\structures\displaycase.dm"
@@ -2079,6 +2079,7 @@
#include "code\modules\mob\living\login.dm"
#include "code\modules\mob\living\logout.dm"
#include "code\modules\mob\living\say.dm"
+#include "code\modules\mob\living\whisper.dm"
#include "code\modules\mob\living\bot\bot.dm"
#include "code\modules\mob\living\bot\cleanbot.dm"
#include "code\modules\mob\living\bot\ed209bot.dm"
@@ -2146,7 +2147,6 @@
#include "code\modules\mob\living\carbon\human\unarmed_attack.dm"
#include "code\modules\mob\living\carbon\human\update_icons.dm"
#include "code\modules\mob\living\carbon\human\virtual_reality_mob.dm"
-#include "code\modules\mob\living\carbon\human\whisper.dm"
#include "code\modules\mob\living\carbon\human\species\species.dm"
#include "code\modules\mob\living\carbon\human\species\species_attack.dm"
#include "code\modules\mob\living\carbon\human\species\species_damage.dm"
diff --git a/code/__defines/materials.dm b/code/__defines/materials.dm
index e3e5f111637..682b02d2488 100644
--- a/code/__defines/materials.dm
+++ b/code/__defines/materials.dm
@@ -57,13 +57,6 @@
#define MATERIAL_CLOTH "cloth"
#define MATERIAL_COTTON "cotton"
#define MATERIAL_CARPET "carpet"
-#define MATERIAL_CLOTH_TEAL "teal"
-#define MATERIAL_CLOTH_BLACK "black"
-#define MATERIAL_CLOTH_GREEN "green"
-#define MATERIAL_CLOTH_PURPLE "purple"
-#define MATERIAL_CLOTH_BLUE "blue"
-#define MATERIAL_CLOTH_BEIGE "beige"
-#define MATERIAL_CLOTH_LIME "lime"
#define MATERIAL_ALTERATION_NONE 0
#define MATERIAL_ALTERATION_NAME 1
diff --git a/code/controllers/subsystems/evac.dm b/code/controllers/subsystems/evac.dm
index ad8d73d0202..a23938e0ec0 100644
--- a/code/controllers/subsystems/evac.dm
+++ b/code/controllers/subsystems/evac.dm
@@ -14,4 +14,5 @@ var/datum/controller/subsystem/evac/SSevac
evacuation_controller.set_up()
/datum/controller/subsystem/evac/fire()
- evacuation_controller.process()
\ No newline at end of file
+ evacuation_controller.process()
+
\ No newline at end of file
diff --git a/code/controllers/subsystems/evacuation/evacuation_shuttle.dm b/code/controllers/subsystems/evacuation/evacuation_shuttle.dm
index 97283525350..f443375cb5b 100644
--- a/code/controllers/subsystems/evacuation/evacuation_shuttle.dm
+++ b/code/controllers/subsystems/evacuation/evacuation_shuttle.dm
@@ -37,9 +37,14 @@
pod.launch(src)
if(autopilot && shuttle.moving_status == SHUTTLE_IDLE)
- evac_arrival_time = world.time + (shuttle.move_time*10) + (shuttle.warmup_time*10)
shuttle.launch(src)
- // Announcements, state changes and such are handled by the shuttle itself to prevent desync.
+
+ state = EVAC_IN_TRANSIT
+
+ if (emergency_evacuation)
+ priority_announcement.Announce(replacetext(replacetext(current_map.emergency_shuttle_leaving_dock, "%dock%", "[current_map.dock_name]"), "%ETA%", "[round(get_eta()/60,1)] minute\s"))
+ else
+ priority_announcement.Announce(replacetext(replacetext(current_map.shuttle_leaving_dock, "%dock%", "[current_map.dock_name]"), "%ETA%", "[round(get_eta()/60,1)] minute\s"))
/datum/evacuation_controller/shuttle/finish_preparing_evac()
departed = 1
diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm
index 2928d9e6a0a..e7e8aa9b1ed 100644
--- a/code/controllers/verbs.dm
+++ b/code/controllers/verbs.dm
@@ -20,6 +20,7 @@
if (!Master.initializing && SS.flags & SS_NO_DISPLAY)
continue
available_controllers[SS.name] = SS
+ available_controllers["Evacuation Main Controller"] = evacuation_controller
var/css = input("What controller would you like to debug?", "Controllers") as null|anything in available_controllers
debug_variables(available_controllers[css])
diff --git a/code/datums/outfits/outfit_antag.dm b/code/datums/outfits/outfit_antag.dm
index d74fd78a2df..c7dafe60e0f 100644
--- a/code/datums/outfits/outfit_antag.dm
+++ b/code/datums/outfits/outfit_antag.dm
@@ -224,7 +224,7 @@
suit = list(
/obj/item/clothing/suit/pirate,
/obj/item/clothing/suit/storage/toggle/bomber,
- /obj/item/clothing/suit/unathi/mantle,
+ /obj/item/clothing/accessory/poncho/unathimantle,
/obj/item/clothing/accessory/poncho,
/obj/item/clothing/accessory/poncho/purple,
/obj/item/clothing/accessory/poncho/roles/cloak/captain,
diff --git a/code/game/gamemodes/events/holidays/Holidays.dm b/code/game/gamemodes/events/holidays/Holidays.dm
index f733b6b0b1d..94d7a3ae3c5 100644
--- a/code/game/gamemodes/events/holidays/Holidays.dm
+++ b/code/game/gamemodes/events/holidays/Holidays.dm
@@ -114,7 +114,6 @@ var/global/Holiday = null
switch(DD)
if(10) Holiday = "Human-Rights Day"
if(14) Holiday = "Monkey Day"
- if(22) Holiday = "Orgasming Day" //lol. These all actually exist
if(24) Holiday = "Christmas Eve"
if(25) Holiday = "Christmas"
if(26) Holiday = "Boxing Day"
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index d30821024c9..27412b7ce3e 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -135,6 +135,14 @@
/obj/effect/meteor/Collide(atom/A)
..()
+ if(istype(A, /obj/effect/energy_field))
+ hitpwr *= 0.5
+ A.ex_act(hitpwr)
+ visible_message(SPAN_DANGER("\The [src] breaks into dust!"))
+ make_debris()
+ msg_admin_attack("Meteor collided with shields at (JMP)")
+ qdel(src)
+
if(A && !QDELETED(src)) // Prevents explosions and other effects when we were deleted by whatever we Bumped() - currently used by shields.
ram_turf(get_turf(A))
get_hit() //should only get hit once per move attempt
diff --git a/code/game/gamemodes/technomancer/spells/mend_organs.dm b/code/game/gamemodes/technomancer/spells/mend_organs.dm
index d819e947711..1b440605ba3 100644
--- a/code/game/gamemodes/technomancer/spells/mend_organs.dm
+++ b/code/game/gamemodes/technomancer/spells/mend_organs.dm
@@ -48,7 +48,7 @@
affected.status &= ~ORGAN_BROKEN
if(affected.tendon_status() & TENDON_CUT)
- affected.tendon.heal()
+ affected.tendon.rejuvenate()
if(E.status & ORGAN_ARTERY_CUT)
E.status &= ~ORGAN_ARTERY_CUT
diff --git a/code/game/machinery/case_button.dm b/code/game/machinery/case_button.dm
index 2349a035a02..56de69d534d 100644
--- a/code/game/machinery/case_button.dm
+++ b/code/game/machinery/case_button.dm
@@ -107,7 +107,7 @@
/obj/machinery/case_button/shuttle/activate(mob/user)
..()
- return call_shuttle_proc(user)
+ return call_shuttle_proc(user, TRUE)
/obj/machinery/case_button/shuttle/deactivate(mob/user)
..()
diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm
index f8129588b2c..06af46792be 100644
--- a/code/game/objects/items/bodybag.dm
+++ b/code/game/objects/items/bodybag.dm
@@ -8,6 +8,7 @@
w_class = ITEMSIZE_SMALL
drop_sound = 'sound/items/drop/cloth.ogg'
pickup_sound = 'sound/items/pickup/cloth.ogg'
+ var/deploy_type = /obj/structure/closet/body_bag
/obj/item/bodybag/attack_self(mob/user)
deploy_bag(user, user.loc)
@@ -21,11 +22,15 @@
deploy_bag(user, target)
/obj/item/bodybag/proc/deploy_bag(mob/user, atom/location)
- var/obj/structure/closet/body_bag/R = new /obj/structure/closet/body_bag(location)
+ var/obj/structure/closet/body_bag/R = new deploy_type(location)
R.add_fingerprint(user)
+ tweak_bag(R)
playsound(src, 'sound/items/drop/cloth.ogg', 30)
qdel(src)
+/obj/item/bodybag/proc/tweak_bag(var/obj/structure/closet/body_bag/BB)
+ return
+
/obj/item/storage/box/bodybags
name = "body bags"
desc = "This box contains body bags."
@@ -156,15 +161,12 @@
icon = 'icons/obj/cryobag.dmi'
icon_state = "bodybag_folded"
origin_tech = list(TECH_BIO = 4)
+ deploy_type = /obj/structure/closet/body_bag/cryobag
var/stasis_power
-/obj/item/bodybag/cryobag/attack_self(mob/user)
- var/obj/structure/closet/body_bag/cryobag/R = new /obj/structure/closet/body_bag/cryobag(user.loc)
+/obj/item/bodybag/cryobag/tweak_bag(var/obj/structure/closet/body_bag/cryobag/C)
if(stasis_power)
- R.stasis_power = stasis_power
- R.update_icon()
- R.add_fingerprint(user)
- qdel(src)
+ C.stasis_power = stasis_power
/obj/structure/closet/body_bag/cryobag
name = "stasis bag"
diff --git a/code/game/objects/items/devices/floor_painter.dm b/code/game/objects/items/devices/floor_painter.dm
index 407a148ef94..54855ed8b88 100644
--- a/code/game/objects/items/devices/floor_painter.dm
+++ b/code/game/objects/items/devices/floor_painter.dm
@@ -76,14 +76,23 @@
var/obj/structure/heavy_vehicle_frame/EF = A
if(istype(EF))
+ playsound(get_turf(src), 'sound/effects/spray3.ogg', 30, 1, -6)
EF.set_colour(paint_colour)
return
var/obj/item/mech_component/MC = A
if(istype(MC))
+ playsound(get_turf(src), 'sound/effects/spray3.ogg', 30, 1, -6)
MC.set_colour(paint_colour)
return
+ var/obj/structure/bed/B = A
+ if(istype(B))
+ playsound(get_turf(src), 'sound/effects/spray3.ogg', 30, 1, -6)
+ B.set_colour(paint_colour)
+ B.update_icon()
+ return
+
var/turf/simulated/floor/F = A
if(!istype(F))
to_chat(user, "\The [src] can only be used on station flooring.")
diff --git a/code/game/objects/items/weapons/storage/business_card.dm b/code/game/objects/items/weapons/storage/business_card.dm
index 7910cc664b6..1ad7da1354d 100644
--- a/code/game/objects/items/weapons/storage/business_card.dm
+++ b/code/game/objects/items/weapons/storage/business_card.dm
@@ -41,6 +41,12 @@
var/last_flash = 0 //spam limiter
can_fold = FALSE
+/obj/item/paper/business_card/update_icon()
+ . = ..()
+ if(worn_overlay)
+ cut_overlays()
+ add_overlay(overlay_image(icon, worn_overlay, flags=RESET_COLOR))
+
/obj/item/paper/business_card/attack_self(mob/living/user)
if(last_flash <= world.time - 20)
last_flash = world.time
diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm
deleted file mode 100644
index 0978deb50c9..00000000000
--- a/code/game/objects/structures/coathanger.dm
+++ /dev/null
@@ -1,74 +0,0 @@
-/obj/structure/coatrack
- name = "coat rack"
- desc = "Rack that holds coats."
- icon = 'icons/obj/coatrack.dmi'
- icon_state = "coatrack0"
- var/obj/item/clothing/suit/coat
- var/obj/item/clothing/head/hat
- var/list/allowed_coats = list(/obj/item/clothing/suit/storage/toggle/labcoat, /obj/item/clothing/suit/storage/toggle/det_trench,
- /obj/item/clothing/suit/storage/toggle/forensics, /obj/item/clothing/suit/storage/toggle/trench,
- /obj/item/clothing/suit/storage/det_jacket, /obj/item/clothing/accessory/poncho/tajarancloak)
- var/list/allowed_hats = list(/obj/item/clothing/head/det, /obj/item/clothing/head/beret/security, /obj/item/clothing/head/softcap/security)
-
-/obj/structure/coatrack/attack_hand(mob/user as mob)
- if (!ishuman(user))
- return
- if(user.incapacitated())
- return
- if (!user.can_use_hand())
- return
- if(coat)
- user.visible_message("[user] takes [coat] off \the [src].", SPAN_NOTICE("You take [coat] off the \the [src]."))
- user.put_in_hands(coat)
- coat = null
- update_icon()
- else if(hat)
- user.visible_message("[user] takes [hat] off \the [src].", SPAN_NOTICE("You take [hat] off the \the [src]."))
- user.put_in_hands(hat)
- hat = null
- update_icon()
-
-/obj/structure/coatrack/attackby(obj/item/W as obj, mob/user as mob)
- if (is_type_in_list(W, allowed_coats) && !coat)
- user.visible_message("[user] hangs [W] on \the [src].", SPAN_NOTICE("You hang [W] on the \the [src]."))
- coat = W
- user.drop_from_inventory(coat, src)
- update_icon()
- else if (is_type_in_list(W, allowed_hats) && !hat)
- user.visible_message("[user] hangs [W] on \the [src].", SPAN_NOTICE("You hang [W] on the \the [src]."))
- hat = W
- user.drop_from_inventory(hat, src)
- update_icon()
- else
- to_chat(user, SPAN_NOTICE("You cannot hang [W] on [src]."))
- return ..()
-
-/obj/structure/coatrack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if (is_type_in_list(mover, allowed_coats) && !coat)
- src.visible_message("[mover] lands on \the [src].")
- coat = mover
- coat.forceMove(src)
- update_icon()
- return 0
- if (is_type_in_list(mover, allowed_hats) && !hat)
- src.visible_message("[mover] lands on \the [src].")
- hat = mover
- hat.forceMove(src)
- update_icon()
- return 0
- else
- return 1
-
-/obj/structure/coatrack/update_icon()
- cut_overlays()
- if (coat)
- if(istype(coat, /obj/item/clothing/suit/storage/toggle))
- var/obj/item/clothing/suit/storage/toggle/T = coat
- T.icon_state = initial(T.icon_state)
- T.opened = FALSE
- add_overlay("coat_[coat.icon_state]")
- if (hat)
- if(istype(hat, /obj/item/clothing/head/softcap/security/idris) || istype(hat, /obj/item/clothing/head/softcap/security/corp))
- add_overlay("hat_softcap_[hat.icon_state]")
- else
- add_overlay("hat_[hat.icon_state]")
diff --git a/code/game/objects/structures/coatrack.dm b/code/game/objects/structures/coatrack.dm
new file mode 100644
index 00000000000..23eaa028bd7
--- /dev/null
+++ b/code/game/objects/structures/coatrack.dm
@@ -0,0 +1,138 @@
+/obj/structure/coatrack
+ name = "coat rack"
+ desc = "Rack that holds coats, or hats, if you're so inclined."
+ icon = 'icons/obj/coatrack.dmi'
+ icon_state = "coatrack"
+ layer = ABOVE_MOB_LAYER //Hide behind coat racks. Because funny.
+ var/obj/item/clothing/coat
+ var/obj/item/clothing/head/hat
+ var/list/custom_sprites = list(/obj/item/clothing/head/beret/security, /obj/item/clothing/accessory/poncho/tajarancloak) // Custom manual sprite override.
+
+/obj/structure/coatrack/attack_hand(mob/user as mob)
+ if(use_check_and_message(user))
+ return
+ if(coat && hat)
+ var/response = ""
+ response = alert(user, "Do you remove the coat, or the hat?", "Coat Rack Selection", "Coat", "Hat", "Cancel")
+ if(response == "Coat")
+ remove_coat(user)
+ if(response == "Hat")
+ remove_hat(user)
+ if(coat)
+ remove_coat(user)
+ if(hat)
+ remove_hat(user)
+ add_fingerprint(user)
+ return
+
+/obj/structure/coatrack/proc/remove_coat(mob/user as mob)
+ user.visible_message("[user] takes [coat] off \the [src].", SPAN_NOTICE("You take [coat] off the \the [src]."))
+ user.put_in_hands(coat)
+ coat = null
+ update_icon()
+
+/obj/structure/coatrack/proc/remove_hat(mob/user as mob)
+ user.visible_message("[user] takes [hat] off \the [src].", SPAN_NOTICE("You take [hat] off the \the [src]."))
+ user.put_in_hands(hat)
+ hat = null
+ update_icon()
+
+/obj/structure/coatrack/attackby(obj/item/W as obj, mob/user as mob)
+ if(use_check_and_message(user))
+ return
+ if(!coat && (istype(W, /obj/item/clothing/suit/storage/toggle) || istype(W, /obj/item/clothing/accessory/poncho)))
+ user.visible_message("[user] hangs [W] on \the [src].", SPAN_NOTICE("You hang [W] on the \the [src]."))
+ coat = W
+ user.drop_from_inventory(coat, src)
+ playsound(src, W.drop_sound, DROP_SOUND_VOLUME)
+ update_icon()
+ else if(!hat && istype(W, /obj/item/clothing/head) && !istype(W, /obj/item/clothing/head/helmet))
+ user.visible_message("[user] hangs [W] on \the [src].", SPAN_NOTICE("You hang [W] on the \the [src]."))
+ hat = W
+ user.drop_from_inventory(hat, src)
+ playsound(src, W.drop_sound, DROP_SOUND_VOLUME)
+ update_icon()
+ else if(istype(W, /obj/item/clothing))
+ to_chat(user, SPAN_WARNING("You can't hang that up."))
+ else
+ return ..()
+
+/obj/structure/coatrack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(!coat && (istype(mover, /obj/item/clothing/suit/storage/toggle) || istype(mover, /obj/item/clothing/accessory/poncho)))
+ src.visible_message("[mover] lands on \the [src].")
+ coat = mover
+ coat.forceMove(src)
+ update_icon()
+ return 0
+ else if(!hat && istype(mover, /obj/item/clothing/head))
+ src.visible_message("[mover] lands on \the [src].")
+ hat = mover
+ hat.forceMove(src)
+ update_icon()
+ return 0
+ else
+ return 1
+
+/obj/structure/coatrack/update_icon()
+ cut_overlays()
+ if(coat)
+ if(is_type_in_list(coat, custom_sprites))
+ add_overlay(coat.icon_state)
+ else if(istype(coat, /obj/item/clothing/suit/storage/toggle)) // Using onmob sprites, because they're more consistent than object sprites.
+ var/obj/item/clothing/suit/storage/toggle/T = coat
+ if(!T.opened)
+ T.opened = TRUE // Makes coats open when hung up. Cause you know, you can't really hang up a closed coat. Well you can, but...code reasons.
+ T.icon_state = "[T.icon_state]_open"
+ handle_coat_image(T)
+ else if(istype(coat, /obj/item/clothing/accessory/poncho)) // Pain.
+ var/obj/item/clothing/accessory/poncho/T = coat
+ handle_coat_image(T)
+ if(hat)
+ if(is_type_in_list(hat, custom_sprites))
+ add_overlay(hat.icon_state)
+ else if(istype(hat, /obj/item/clothing/head))
+ var/obj/item/clothing/head/H = hat
+ var/matrix/M = matrix()
+ var/image/hat_image
+ if(H.contained_sprite)
+ var/hat_icon_state = "[H.icon_state][WORN_HEAD]" // Needed to bypass contained sprite phoney baloney.
+ hat_image = image(H.icon, hat_icon_state, src.layer, EAST)
+ if(H.build_from_parts)
+ hat_image.add_overlay(overlay_image(H.icon, "[H.icon_state]_[H.worn_overlay]", flags=RESET_COLOR))
+ else
+ hat_image = image(INV_HEAD_DEF_ICON, H.icon_state, src.layer, EAST)
+ if(H.build_from_parts)
+ hat_image.add_overlay(overlay_image(icon, "[INV_HEAD_DEF_ICON]_[H.worn_overlay]", flags=RESET_COLOR))
+ M.Turn(90) // Flip the hat over and stick it on the coatrack.
+ M.Translate(-6, 6)
+ hat_image.transform = M
+ add_overlay(hat_image)
+
+/obj/structure/coatrack/proc/handle_coat_image(var/obj/item/clothing/T)
+ var/icon/coat_outline = icon('icons/obj/coatrack.dmi', "outline")
+ var/matrix/M = matrix()
+ var/coat_icon_state = T.icon_state
+ var/coat_icon_file = INV_SUIT_DEF_ICON
+ if(T.contained_sprite)
+ coat_icon_state = "[T.icon_state][WORN_SUIT]" // Needed to bypass contained sprite phoney baloney.
+ coat_icon_file = T.icon
+
+ var/icon/coat_icon = new(coat_icon_file, coat_icon_state)
+
+ coat_icon.Blend(coat_outline, ICON_OVERLAY)
+ coat_icon.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) //Slice the coat in half.
+ var/image/coat_image = image(coat_icon)
+ if(T.color)
+ coat_image.color = T.color
+
+ if(T.build_from_parts)
+ var/icon/overlay_icon = new(coat_icon_file, "[coat_icon_state]_[T.worn_overlay]")
+ overlay_icon.Blend(coat_outline, ICON_OVERLAY)
+ overlay_icon.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0)) // Slice the overlay in half and slap it on the coat.
+ var/image/overlay_image = image(overlay_icon)
+ overlay_image.appearance_flags = RESET_COLOR
+ coat_image.add_overlay(overlay_image)
+
+ M.Translate(-1, 5) // Stick it on the coat rack.
+ coat_image.transform = M
+ add_overlay(coat_image)
diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm
index c2ed18f3288..4df7cb2242e 100644
--- a/code/game/objects/structures/crates_lockers/closets/statue.dm
+++ b/code/game/objects/structures/crates_lockers/closets/statue.dm
@@ -5,7 +5,7 @@
/mob/statue_mob/send_emote()
to_chat(src, "You are unable to move while trapped as a statue.")
-/mob/statue_mob/say()
+/mob/statue_mob/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
to_chat(src, "You are unable to speak while trapped as a statue.")
/obj/structure/closet/statue
@@ -192,4 +192,4 @@
dump_contents()
visible_message("\The [src] shatters!")
- qdel(src)
\ No newline at end of file
+ qdel(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
index c4898510f28..f7bac249fd6 100644
--- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
+++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
@@ -120,7 +120,7 @@
/obj/structure/closet/wardrobe/xenos/fill()
..()
- new /obj/item/clothing/suit/unathi/mantle(src)
+ new /obj/item/clothing/accessory/poncho/unathimantle(src)
new /obj/item/clothing/suit/unathi/robe/beige(src)
new /obj/item/clothing/shoes/footwraps(src)
new /obj/item/clothing/shoes/footwraps(src)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index 7018296fb71..4e5edfd2fd9 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -25,6 +25,8 @@
var/material_alteration = MATERIAL_ALTERATION_ALL
var/buckling_sound = 'sound/effects/buckle.ogg'
+ var/painted_colour // Used for paint gun and preset colours. I know this name sucks.
+
var/can_dismantle = TRUE
var/can_pad = TRUE
@@ -41,7 +43,7 @@
. = ..()
LAZYADD(can_buckle, /mob/living)
-/obj/structure/bed/New(newloc, new_material = MATERIAL_STEEL, new_padding_material)
+/obj/structure/bed/New(newloc, new_material = MATERIAL_STEEL, new_padding_material, new_painted_colour)
..(newloc)
if(can_buckle)
desc_info = "Click and drag yourself (or anyone) to this to buckle in. Click on this with an empty hand to undo the buckles.
\
@@ -55,6 +57,8 @@
return
if(new_padding_material)
padding_material = SSmaterials.get_material_by_name(new_padding_material)
+ if(new_painted_colour)
+ painted_colour = new_painted_colour
update_icon()
/obj/structure/bed/buckle(mob/living/M)
@@ -80,10 +84,13 @@
// Padding overlay.
if(padding_material)
var/padding_cache_key = "[base_icon]-[padding_material.name]-padding"
- if(!furniture_cache[padding_cache_key])
+ if(!furniture_cache[padding_cache_key] || painted_colour) //avoid having to regenerate the image everytime unless painted.
var/image/I = image(icon, "[base_icon]_padding")
if(material_alteration & MATERIAL_ALTERATION_COLOR)
- I.color = padding_material.icon_colour
+ if(painted_colour)
+ I.color = painted_colour
+ else
+ I.color = padding_material.icon_colour
furniture_cache[padding_cache_key] = I
add_overlay(furniture_cache[padding_cache_key])
@@ -93,8 +100,13 @@
if(material_alteration & MATERIAL_ALTERATION_DESC)
desc = initial(desc)
- desc += padding_material ? " It's made of [material.use_name] and covered with [padding_material.use_name]." : " It's made of [material.use_name]."
+ desc += padding_material ? " It's made of [material.use_name] and covered with [padding_material.use_name][painted_colour ? ", colored in [painted_colour]" : ""]." : " It's made of [material.use_name]." //Yeah plain hex codes suck but at least it's a little funny and less of a headache for players.
+/obj/structure/bed/proc/set_colour(new_colour)
+ if(padding_material)
+ var/last_colour = painted_colour
+ painted_colour = new_colour
+ return painted_colour != last_colour
/obj/structure/bed/forceMove(atom/dest)
. = ..()
@@ -162,6 +174,7 @@
return
to_chat(user, "You remove the padding from \the [src].")
playsound(src, 'sound/items/wirecutter.ogg', 100, 1)
+ painted_colour = null
remove_padding()
else if (W.isscrewdriver())
@@ -197,6 +210,9 @@
W.pixel_x = 10 //make sure they reach the pillow
W.pixel_y = -6
+ else if(istype(W, /obj/item/device/floor_painter))
+ return
+
else if(!istype(W, /obj/item/bedsheet))
..()
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index 510e71533ad..be3c40db27f 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -42,7 +42,10 @@
if(!furniture_cache[padding_cache_key])
var/image/I = image(icon, "[base_icon]_padding_over")
if(material_alteration & MATERIAL_ALTERATION_COLOR)
- I.color = padding_material.icon_colour
+ if(painted_colour)
+ I.color = painted_colour
+ else if(padding_material.icon_colour)
+ I.color = padding_material.icon_colour
I.layer = FLY_LAYER
furniture_cache[padding_cache_key] = I
add_overlay(furniture_cache[padding_cache_key])
@@ -62,7 +65,10 @@
var/image/I = image(icon, "[base_icon]_padding_armrest")
I.layer = FLY_LAYER
if(material_alteration & MATERIAL_ALTERATION_COLOR)
- I.color = padding_material.icon_colour
+ if(painted_colour)
+ I.color = painted_colour
+ else if(padding_material.icon_colour)
+ I.color = padding_material.icon_colour
furniture_cache[cache_key] = I
add_overlay(furniture_cache[cache_key])
@@ -84,33 +90,42 @@
if(mover.density && isliving(mover) && (reverse_dir[dir] & angle2dir(Get_Angle(src, mover))))
return FALSE
return ..()
-
+
/obj/structure/bed/stool/chair/padded/brown/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_LEATHER)
+/obj/structure/bed/stool/chair/padded/black/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_DARK_GRAY)
+
+/obj/structure/bed/stool/chair/padded/beige/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BEIGE)
+
/obj/structure/bed/stool/chair/padded/red/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_CARPET)
-/obj/structure/bed/stool/chair/padded/teal/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_TEAL)
+/obj/structure/bed/stool/chair/padded/orange/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_ORANGE)
-/obj/structure/bed/stool/chair/padded/black/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLACK)
+/obj/structure/bed/stool/chair/padded/yellow/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_YELLOW)
/obj/structure/bed/stool/chair/padded/green/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_GREEN)
-
-/obj/structure/bed/stool/chair/padded/purp/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_PURPLE)
-
-/obj/structure/bed/stool/chair/padded/blue/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLUE)
-
-/obj/structure/bed/stool/chair/padded/beige/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BEIGE)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_GREEN)
/obj/structure/bed/stool/chair/padded/lime/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_LIME)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_LIME)
+
+/obj/structure/bed/stool/chair/padded/blue/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BLUE)
+
+/obj/structure/bed/stool/chair/padded/teal/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_TEAL)
+
+/obj/structure/bed/stool/chair/padded/purple/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_PURPLE)
+
+/obj/structure/bed/stool/chair/padded/violet/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_VIOLET)
/obj/structure/bed/stool/chair/sofa
name = "sofa"
@@ -121,29 +136,38 @@
/obj/structure/bed/stool/chair/sofa/brown/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_LEATHER)
+/obj/structure/bed/stool/chair/sofa/black/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_DARK_GRAY)
+
+/obj/structure/bed/stool/chair/sofa/beige/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BEIGE)
+
/obj/structure/bed/stool/chair/sofa/red/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_CARPET)
-/obj/structure/bed/stool/chair/sofa/teal/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_TEAL)
+/obj/structure/bed/stool/chair/sofa/orange/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_ORANGE)
-/obj/structure/bed/stool/chair/sofa/black/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLACK)
+/obj/structure/bed/stool/chair/sofa/yellow/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_YELLOW)
/obj/structure/bed/stool/chair/sofa/green/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_GREEN)
-
-/obj/structure/bed/stool/chair/sofa/purp/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_PURPLE)
-
-/obj/structure/bed/stool/chair/sofa/blue/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLUE)
-
-/obj/structure/bed/stool/chair/sofa/beige/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_GREEN)
/obj/structure/bed/stool/chair/sofa/lime/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_LIME)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_LIME)
+
+/obj/structure/bed/stool/chair/sofa/blue/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BLUE)
+
+/obj/structure/bed/stool/chair/sofa/teal/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_TEAL)
+
+/obj/structure/bed/stool/chair/sofa/purple/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_PURPLE)
+
+/obj/structure/bed/stool/chair/sofa/violet/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_VIOLET)
/obj/structure/bed/stool/chair/sofa/left
icon_state = "sofaend_left_preview"
@@ -152,29 +176,38 @@
/obj/structure/bed/stool/chair/sofa/left/brown/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_LEATHER)
+/obj/structure/bed/stool/chair/sofa/left/black/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_DARK_GRAY)
+
+/obj/structure/bed/stool/chair/sofa/left/beige/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BEIGE)
+
/obj/structure/bed/stool/chair/sofa/left/red/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_CARPET)
-/obj/structure/bed/stool/chair/sofa/left/teal/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_TEAL)
+/obj/structure/bed/stool/chair/sofa/left/orange/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_ORANGE)
-/obj/structure/bed/stool/chair/sofa/left/black/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLACK)
+/obj/structure/bed/stool/chair/sofa/left/yellow/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_YELLOW)
/obj/structure/bed/stool/chair/sofa/left/green/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_GREEN)
-
-/obj/structure/bed/stool/chair/sofa/left/purp/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_PURPLE)
-
-/obj/structure/bed/stool/chair/sofa/left/blue/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLUE)
-
-/obj/structure/bed/stool/chair/sofa/left/beige/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_GREEN)
/obj/structure/bed/stool/chair/sofa/left/lime/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_LIME)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_LIME)
+
+/obj/structure/bed/stool/chair/sofa/left/blue/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BLUE)
+
+/obj/structure/bed/stool/chair/sofa/left/teal/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_TEAL)
+
+/obj/structure/bed/stool/chair/sofa/left/purple/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_PURPLE)
+
+/obj/structure/bed/stool/chair/sofa/left/violet/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_VIOLET)
/obj/structure/bed/stool/chair/sofa/right
icon_state = "sofaend_right_preview"
@@ -183,29 +216,39 @@
/obj/structure/bed/stool/chair/sofa/right/brown/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_LEATHER)
+/obj/structure/bed/stool/chair/sofa/right/black/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_DARK_GRAY)
+
+/obj/structure/bed/stool/chair/sofa/right/beige/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BEIGE)
+
/obj/structure/bed/stool/chair/sofa/right/red/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_CARPET)
-/obj/structure/bed/stool/chair/sofa/right/teal/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_TEAL)
+/obj/structure/bed/stool/chair/sofa/right/orange/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_ORANGE)
-/obj/structure/bed/stool/chair/sofa/right/black/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLACK)
+/obj/structure/bed/stool/chair/sofa/right/yellow/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_YELLOW)
/obj/structure/bed/stool/chair/sofa/right/green/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_GREEN)
-
-/obj/structure/bed/stool/chair/sofa/right/purp/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_PURPLE)
-
-/obj/structure/bed/stool/chair/sofa/right/blue/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLUE)
-
-/obj/structure/bed/stool/chair/sofa/right/beige/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_GREEN)
/obj/structure/bed/stool/chair/sofa/right/lime/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_LIME)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_LIME)
+
+/obj/structure/bed/stool/chair/sofa/right/blue/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BLUE)
+
+/obj/structure/bed/stool/chair/sofa/right/teal/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_TEAL)
+
+/obj/structure/bed/stool/chair/sofa/right/purple/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_PURPLE)
+
+/obj/structure/bed/stool/chair/sofa/right/violet/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_VIOLET)
+
/obj/structure/bed/stool/chair/sofa/corner
icon_state = "sofacorner_preview"
@@ -214,29 +257,38 @@
/obj/structure/bed/stool/chair/sofa/corner/brown/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_LEATHER)
+/obj/structure/bed/stool/chair/sofa/corner/black/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_DARK_GRAY)
+
+/obj/structure/bed/stool/chair/sofa/corner/beige/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BEIGE)
+
/obj/structure/bed/stool/chair/sofa/corner/red/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_CARPET)
-/obj/structure/bed/stool/chair/sofa/corner/teal/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_TEAL)
+/obj/structure/bed/stool/chair/sofa/corner/orange/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_ORANGE)
-/obj/structure/bed/stool/chair/sofa/corner/black/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLACK)
+/obj/structure/bed/stool/chair/sofa/corner/yellow/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_YELLOW)
/obj/structure/bed/stool/chair/sofa/corner/green/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_GREEN)
-
-/obj/structure/bed/stool/chair/sofa/corner/purp/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_PURPLE)
-
-/obj/structure/bed/stool/chair/sofa/corner/blue/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLUE)
-
-/obj/structure/bed/stool/chair/sofa/corner/beige/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_GREEN)
/obj/structure/bed/stool/chair/sofa/corner/lime/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_LIME)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_LIME)
+
+/obj/structure/bed/stool/chair/sofa/corner/blue/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BLUE)
+
+/obj/structure/bed/stool/chair/sofa/corner/teal/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_TEAL)
+
+/obj/structure/bed/stool/chair/sofa/corner/purple/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_PURPLE)
+
+/obj/structure/bed/stool/chair/sofa/corner/violet/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_VIOLET)
/obj/structure/bed/stool/chair/office // For the love of god, don't use this.
@@ -326,6 +378,7 @@
/obj/structure/bed/stool/chair/unmovable
can_dismantle = FALSE
+ held_item = null
/obj/structure/bed/stool/chair/shuttle
name = "shuttle chair"
@@ -335,6 +388,7 @@
material_alteration = MATERIAL_ALTERATION_NAME || MATERIAL_ALTERATION_DESC
can_dismantle = FALSE
anchored = TRUE
+ held_item = null
/obj/structure/bed/stool/chair/shuttle/post_buckle()
if(buckled)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm
index 6c0f3e28727..10c27632dd8 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm
@@ -17,7 +17,7 @@
/obj/structure/bed/stool/MouseDrop(over_object, src_location, over_location)
. = ..()
if(over_object == usr && Adjacent(usr))
- if(!held_item || use_check_and_message(usr) || buckled || !can_dismantle || (anchored && padding_material))
+ if(!held_item || use_check_and_message(usr) || buckled || (anchored && padding_material)) // Make sure held_item = null if you don't want it to get picked up.
return
usr.visible_message(SPAN_NOTICE("[usr] [withdraw_verb]s \the [src.name]."), SPAN_NOTICE("You [withdraw_verb] \the [src.name]."))
var/obj/item/material/stool/S = new held_item(src.loc, material.name, padding_material ? padding_material.name : null) // Handles all the material code so you don't have to.
@@ -28,12 +28,15 @@
S.name = name // Get the name and desc of the stool, rather. We already went through all the trouble in New in bed.dm
if(material_alteration & MATERIAL_ALTERATION_DESC)
S.desc = desc
+ if(painted_colour)
+ S.painted_colour = painted_colour
if(blood_DNA)
S.blood_DNA |= blood_DNA // Transfer blood, if any.
S.add_blood()
S.dir = dir
S.add_fingerprint(usr)
usr.put_in_hands(S)
+ S.update_icon()
qdel(src)
/obj/structure/bed/stool/wood/New(var/newloc)
@@ -45,29 +48,38 @@
/obj/structure/bed/stool/padded/brown/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_LEATHER)
+/obj/structure/bed/stool/padded/black/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_DARK_GRAY)
+
+/obj/structure/bed/stool/padded/beige/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BEIGE)
+
/obj/structure/bed/stool/padded/red/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_CARPET)
-/obj/structure/bed/stool/padded/teal/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_TEAL)
+/obj/structure/bed/stool/padded/orange/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_ORANGE)
-/obj/structure/bed/stool/padded/black/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLACK)
+/obj/structure/bed/stool/padded/yellow/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_YELLOW)
/obj/structure/bed/stool/padded/green/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_GREEN)
-
-/obj/structure/bed/stool/padded/purp/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_PURPLE)
-
-/obj/structure/bed/stool/padded/blue/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLUE)
-
-/obj/structure/bed/stool/padded/beige/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BEIGE)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_GREEN)
/obj/structure/bed/stool/padded/lime/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_LIME)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_LIME)
+
+/obj/structure/bed/stool/padded/blue/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BLUE)
+
+/obj/structure/bed/stool/padded/teal/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_TEAL)
+
+/obj/structure/bed/stool/padded/purple/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_PURPLE)
+
+/obj/structure/bed/stool/padded/violet/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_VIOLET)
/obj/structure/bed/stool/wood/New(var/newloc)
..(newloc, MATERIAL_WOOD)
@@ -86,32 +98,45 @@
/obj/structure/bed/stool/bar/padded
icon_state = "bar_stool_padded_preview"
+// ROYGBIV colors for convenience. Mappers can use custom hex codes or defines if they want special colors.
+
+
/obj/structure/bed/stool/bar/padded/brown/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_LEATHER)
+/obj/structure/bed/stool/bar/padded/black/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_DARK_GRAY)
+
+/obj/structure/bed/stool/bar/padded/beige/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BEIGE)
+
/obj/structure/bed/stool/bar/padded/red/New(var/newloc)
..(newloc, MATERIAL_STEEL, MATERIAL_CARPET)
-/obj/structure/bed/stool/bar/padded/teal/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_TEAL)
+/obj/structure/bed/stool/bar/padded/orange/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_ORANGE)
-/obj/structure/bed/stool/bar/padded/black/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLACK)
+/obj/structure/bed/stool/bar/padded/yellow/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_YELLOW)
/obj/structure/bed/stool/bar/padded/green/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_GREEN)
-
-/obj/structure/bed/stool/bar/padded/purp/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_PURPLE)
-
-/obj/structure/bed/stool/bar/padded/blue/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BLUE)
-
-/obj/structure/bed/stool/bar/padded/beige/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_BEIGE)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_GREEN)
/obj/structure/bed/stool/bar/padded/lime/New(var/newloc)
- ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH_LIME)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_LIME)
+
+/obj/structure/bed/stool/bar/padded/blue/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_BLUE)
+
+/obj/structure/bed/stool/bar/padded/teal/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_TEAL)
+
+/obj/structure/bed/stool/bar/padded/purple/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_PURPLE)
+
+/obj/structure/bed/stool/bar/padded/violet/New(var/newloc)
+ ..(newloc, MATERIAL_STEEL, MATERIAL_CLOTH, COLOR_VIOLET)
+
/obj/structure/bed/stool/bar/wood/New(var/newloc)
..(newloc, MATERIAL_WOOD)
@@ -152,6 +177,7 @@
var/material/padding_material
var/obj/structure/bed/stool/origin_type = /obj/structure/bed/stool
var/deploy_verb = "right"
+ var/painted_colour
/obj/item/material/stool/New(var/newloc, var/new_material, var/new_padding_material)
..(newloc, new_material) // new_material handled in material_weapons.dm
@@ -231,7 +257,10 @@
padding_overlay.appearance_flags = RESET_COLOR
build_from_parts = TRUE
worn_overlay = "padding"
- if(padding_material.icon_colour)
+ if(painted_colour)
+ padding_overlay.color = painted_colour
+ worn_overlay_color = painted_colour
+ else if(padding_material.icon_colour)
padding_overlay.color = padding_material.icon_colour
worn_overlay_color = padding_material.icon_colour
add_overlay(padding_overlay)
diff --git a/code/game/objects/structures/vr/_remote_chair.dm b/code/game/objects/structures/vr/_remote_chair.dm
index 420d57d2e15..bbf6286d287 100644
--- a/code/game/objects/structures/vr/_remote_chair.dm
+++ b/code/game/objects/structures/vr/_remote_chair.dm
@@ -6,6 +6,7 @@
var/portable_type
can_dismantle = FALSE
var/remote_network // Which network does this remote control belong to?
+ held_item = null
/obj/structure/bed/stool/chair/remote/Initialize()
. = ..()
diff --git a/code/modules/background/citizenship/unathi.dm b/code/modules/background/citizenship/unathi.dm
index 9508bda1a18..99f5e3f2ec0 100644
--- a/code/modules/background/citizenship/unathi.dm
+++ b/code/modules/background/citizenship/unathi.dm
@@ -65,6 +65,6 @@
name = "Izweski Hegemony Consular Officer"
uniform = /obj/item/clothing/under/unathi
- suit = /obj/item/clothing/suit/unathi/mantle
+ suit = /obj/item/clothing/accessory/poncho/unathimantle
backpack_contents = list(/obj/item/device/camera = 1)
belt = /obj/item/gun/energy/pistol/hegemony
diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm
index 22c56152a91..2e2b39b5926 100644
--- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm
@@ -14,6 +14,13 @@
path = /obj/item/clothing/accessory/wcoat_rec
flags = GEAR_HAS_NAME_SELECTION | GEAR_HAS_DESC_SELECTION | GEAR_HAS_COLOR_SELECTION
+/datum/gear/accessory/waistcoat/New()
+ ..()
+ var/list/waistcoats = list()
+ waistcoats["waistcoat"] = /obj/item/clothing/accessory/wcoat_rec
+ waistcoats["waistcoat, alt"] = /obj/item/clothing/accessory/silversun/wcoat
+ gear_tweaks += new /datum/gear_tweak/path(waistcoats)
+
/datum/gear/accessory/chaps
display_name = "chaps selection"
path = /obj/item/clothing/accessory/chaps
diff --git a/code/modules/client/preference_setup/loadout/loadout_utility.dm b/code/modules/client/preference_setup/loadout/loadout_utility.dm
index 4da6c0f9d22..ec9f1b26746 100644
--- a/code/modules/client/preference_setup/loadout/loadout_utility.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_utility.dm
@@ -101,10 +101,6 @@
path = /obj/item/material/stool/chair/wheelchair
cost = 4
-/datum/gear/utility/wheelchair/color/New()
- ..()
- gear_tweaks += gear_tweak_free_color_choice
-
/datum/gear/utility/business_card_holder
display_name = "business card holder"
description = "Comes in different materials."
diff --git a/code/modules/clothing/masks/xeno/unathi.dm b/code/modules/clothing/masks/xeno/unathi.dm
index 09bef00a772..3be92bd4fbb 100644
--- a/code/modules/clothing/masks/xeno/unathi.dm
+++ b/code/modules/clothing/masks/xeno/unathi.dm
@@ -6,5 +6,6 @@
icon = 'icons/obj/unathi_items.dmi'
icon_state = "thakh_mask"
item_state = "thakh_mask"
+ sprite_sheets = null
species_restricted = list(BODYTYPE_UNATHI)
contained_sprite = TRUE
\ No newline at end of file
diff --git a/code/modules/clothing/under/accessories/shirts.dm b/code/modules/clothing/under/accessories/shirts.dm
index d0263bb9520..3c810359d50 100644
--- a/code/modules/clothing/under/accessories/shirts.dm
+++ b/code/modules/clothing/under/accessories/shirts.dm
@@ -282,6 +282,14 @@
icon_state = "hawaii_red"
color = color_rotation(rand(-11,12)*15)
+/obj/item/clothing/accessory/silversun/wcoat
+ name = "waistcoat"
+ desc = "A slick waistcoat."
+ icon = 'icons/obj/clothing/ties.dmi'
+ icon_state = "det_vest"
+ item_state = "det_vest"
+ contained_sprite = FALSE
+
/obj/item/clothing/accessory/university
name = "university sweatshirt"
desc = "A comfy university sweatshirt. This one is grey."
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 64776793da4..809ab587120 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -446,7 +446,7 @@ All custom items with worn sprites must follow the contained sprite system: http
item_state = "zilosnish_uniform"
contained_sprite = TRUE
-/obj/item/clothing/suit/unathi/mantle/fluff/zilosnish_mantle //Exotic Mantle - Zilosnish Szu - sleepywolf
+/obj/item/clothing/accessory/poncho/unathimantle/fluff/zilosnish_mantle //Exotic Mantle - Zilosnish Szu - sleepywolf
name = "exotic mantle"
desc = "A red hide with a gold and jade insignia pin to keep it on a wearers shoulders. The hide is thick, like rhino skin."
icon = 'icons/obj/custom_items/zilosnish_items.dmi'
diff --git a/code/modules/emotes/definitions/_species.dm b/code/modules/emotes/definitions/_species.dm
index 49c2fed9aa4..2dccd84666b 100644
--- a/code/modules/emotes/definitions/_species.dm
+++ b/code/modules/emotes/definitions/_species.dm
@@ -30,7 +30,7 @@
/decl/emote/human/stopsway,
/decl/emote/audible/lizard_bellow,
/decl/emote/audible/hiss,
- /decl/emote/audible/hiss/long,
+ /decl/emote/audible/growl,
/decl/emote/audible/hiss/short
)
pain_emotes_with_pain_level = list(
diff --git a/code/modules/emotes/definitions/audible.dm b/code/modules/emotes/definitions/audible.dm
index abf22eddc90..dc47fba94a0 100644
--- a/code/modules/emotes/definitions/audible.dm
+++ b/code/modules/emotes/definitions/audible.dm
@@ -239,11 +239,17 @@
emote_message_3p_target = "USER hisses softly at TARGET."
emote_message_3p = "USER hisses softly."
-/decl/emote/audible/hiss/long
- key = "hiss2"
+/decl/emote/audible/growl
+ key = "growl"
+ emote_message_3p_target = "USER growls softly at TARGET."
+ emote_message_3p = "USER growls softly."
+ emote_sound = 'sound/voice/Lizardgrowl.ogg'
/decl/emote/audible/hiss/short
- key = "hiss3"
+ key = "hiss2"
+ emote_message_3p_target = "USER hisses softly at TARGET."
+ emote_message_3p = "USER hisses softly."
+ emote_sound = 'sound/voice/lizardhiss2.ogg'
/decl/emote/audible/lizard_bellow
key = "bellow"
diff --git a/code/modules/item_worth/worths_list.dm b/code/modules/item_worth/worths_list.dm
index 5bbaf442f9a..02d727f7324 100644
--- a/code/modules/item_worth/worths_list.dm
+++ b/code/modules/item_worth/worths_list.dm
@@ -476,7 +476,7 @@ var/list/worths = list(
/obj/item/clothing/suit/space/cult = 1050,
/obj/item/clothing/suit/space/emergency = 150,
/obj/item/clothing/suit/space = 730,
- /obj/item/clothing/suit/unathi/mantle = 80,
+ /obj/item/clothing/accessory/poncho/unathimantle = 80,
/obj/item/clothing/suit/cultrobes = 200,
/obj/item/clothing/suit/storage/vest/heavy/ert = 2500,
/obj/item/clothing/suit/armor/carrier/heavy = 3000,
diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm
index e31abc45a56..c8cd3f89c43 100644
--- a/code/modules/materials/material_sheets.dm
+++ b/code/modules/materials/material_sheets.dm
@@ -13,6 +13,7 @@
var/material/material
var/perunit
var/apply_colour //temp pending icon rewrite
+ var/painted_colour
var/use_material_sound = TRUE
/obj/item/stack/material/Initialize(mapload, amount)
@@ -32,7 +33,9 @@
perunit = SHEET_MATERIAL_AMOUNT
if(apply_colour)
- color = material.icon_colour
+ var/image/I = new(icon, icon_state)
+ I.color = material.icon_colour
+ add_overlay(I)
if(use_material_sound) // SEE MATERIALS.DM
drop_sound = material.drop_sound
@@ -61,8 +64,16 @@
/obj/item/stack/material/update_icon()
. = ..()
+ cut_overlays()
if(material)
update_strings()
+ if(apply_colour) // This is ass, but stops maptext from getting colored.
+ var/image/I = new(icon, icon_state)
+ if(!painted_colour)
+ I.color = material.icon_colour
+ else
+ I.color = painted_colour
+ add_overlay(I)
/obj/item/stack/material/transfer_to(obj/item/stack/S, var/tamount=null, var/type_verified)
var/obj/item/stack/material/M = S
@@ -92,7 +103,7 @@
name = "iron"
icon_state = "sheet-silver"
default_type = MATERIAL_IRON
- apply_colour = 1
+ apply_colour = TRUE
/obj/item/stack/material/iron/full/Initialize()
. = ..()
@@ -223,7 +234,7 @@
name = "tritium"
icon_state = "sheet-silver"
default_type = MATERIAL_TRITIUM
- apply_colour = 1
+ apply_colour = TRUE
/obj/item/stack/material/tritium/full/Initialize()
. = ..()
@@ -234,7 +245,7 @@
name = "osmium"
icon_state = "sheet-silver"
default_type = MATERIAL_OSMIUM
- apply_colour = 1
+ apply_colour = TRUE
/obj/item/stack/material/osmium/full/Initialize()
. = ..()
@@ -315,6 +326,7 @@
icon_state = "sheet-cloth"
default_type = MATERIAL_CLOTH
icon_has_variants = TRUE
+ apply_colour = TRUE
/obj/item/stack/material/cloth/full/Initialize()
. = ..()
diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm
index 965f517e117..6b42033b2a6 100644
--- a/code/modules/materials/materials.dm
+++ b/code/modules/materials/materials.dm
@@ -893,48 +893,6 @@
pickup_sound = 'sound/items/pickup/cloth.ogg'
weapon_hitsound = 'sound/weapons/towelwhip.ogg'
-/material/cloth/teal
- name = MATERIAL_CLOTH_TEAL
- display_name ="teal"
- use_name = "teal cloth"
- icon_colour = "#00EAFA"
-
-/material/cloth/black
- name = MATERIAL_CLOTH_BLACK
- display_name = "black"
- use_name = "black cloth"
- icon_colour = "#505050"
-
-/material/cloth/green
- name = MATERIAL_CLOTH_GREEN
- display_name = "green"
- use_name = "green cloth"
- icon_colour = "#01C608"
-
-/material/cloth/purple
- name = MATERIAL_CLOTH_PURPLE
- display_name = "purple"
- use_name = "purple cloth"
- icon_colour = "#9C56C4"
-
-/material/cloth/blue
- name = MATERIAL_CLOTH_BLUE
- display_name = "blue"
- use_name = "blue cloth"
- icon_colour = "#6B6FE3"
-
-/material/cloth/beige
- name = MATERIAL_CLOTH_BEIGE
- display_name = "beige"
- use_name = "beige cloth"
- icon_colour = "#E8E7C8"
-
-/material/cloth/lime
- name = MATERIAL_CLOTH_LIME
- display_name = "lime"
- use_name = "lime cloth"
- icon_colour = "#62E36C"
-
/material/hide //TODO make different hides somewhat different among them
name = MATERIAL_HIDE
stack_origin_tech = list(TECH_MATERIAL = 2)
diff --git a/code/modules/mob/abstract/new_player/sprite_accessories.dm b/code/modules/mob/abstract/new_player/sprite_accessories.dm
index 96828243814..147428d82b4 100644
--- a/code/modules/mob/abstract/new_player/sprite_accessories.dm
+++ b/code/modules/mob/abstract/new_player/sprite_accessories.dm
@@ -1784,7 +1784,14 @@ Follow by example and make good judgement based on length which list to include
skrell_spots
name = "Skrell Spots"
icon_state = "skrell_gradient_spots"
- species_allowed = list(/datum/species/skrell, /datum/species/skrell/axiori)
+ species_allowed = list(/datum/species/skrell, /datum/species/skrell/axiori, /datum/species/zombie/skrell)
+
+ skrell_stripes
+ name = "Skrell Headtail Blotches"
+ icon_state = "skr_headtail_stripes"
+ species_allowed = list(/datum/species/skrell, /datum/species/skrell/axiori, /datum/species/zombie/skrell)
+
+
bulwark_default
name = "Bulwark Horn"
@@ -1809,7 +1816,7 @@ Follow by example and make good judgement based on length which list to include
icon_state = "bald"
gender = NEUTER
species_allowed = list(/datum/species/human,/datum/species/human/offworlder,/datum/species/machine/shell,/datum/species/machine/shell/rogue,/datum/species/zombie,/datum/species/unathi,/datum/species/zombie/unathi,
- /datum/species/tajaran,/datum/species/tajaran/zhan_khazan,/datum/species/tajaran/m_sai,/datum/species/zombie/tajara,/datum/species/skrell,/datum/species/skrell/axiori,/datum/species/zombie/skrell,/datum/species/diona,
+ /datum/species/tajaran,/datum/species/tajaran/zhan_khazan,/datum/species/tajaran/m_sai,/datum/species/zombie/tajara,/datum/species/skrell,/datum/species/skrell/axiori,/datum/species/zombie/skrell,/datum/species/diona,
/datum/species/diona/coeu, /datum/species/bug/type_b)
threeOclock
@@ -2578,7 +2585,7 @@ Follow by example and make good judgement based on length which list to include
icon_state = "hair_swoop"
length = 2
chatname = "styled mane"
-
+
taj_ears_swoop_alt
name = "Tajara Swoop Alt"
icon_state = "hair_swoop_alt"
@@ -2971,14 +2978,14 @@ Follow by example and make good judgement based on length which list to include
icon_state = "bully_inj_left"
chatname = "antenna"
length = 1
-
- bulwark_damaged_right
+
+ bulwark_damaged_right
name = "Bulwark Injured Antenna, Right"
icon_state = "bully_inj_right"
chatname = "antenna"
length = 1
- bulwark_knight
+ bulwark_knight
name = "Bulwark Knight Antennae"
icon_state = "bully_knight"
chatname = "antennae"
@@ -3542,11 +3549,11 @@ Follow by example and make good judgement based on length which list to include
name = "Bulldog Mandibles"
icon_state = "vaurca_bulldog"
- mantis
+ mantis
name = "Mantis Mandibles"
icon_state = "vaurca_mantis"
- stag
+ stag
name = "Stag Mandibles"
icon_state = "vaurca_stag"
@@ -3554,11 +3561,11 @@ Follow by example and make good judgement based on length which list to include
name = "Ectatomma Mandibles"
icon_state = "vaurca_ectatomma"
- horridus
+ horridus
name = "Horridus Mandibles"
icon_state = "vaurca_horridus"
- tusks
+ tusks
name = "Tusk Mandibles"
icon_state = "vaurca_tusks"
@@ -3566,7 +3573,7 @@ Follow by example and make good judgement based on length which list to include
name = "Acanthognathus Mandibles"
icon_state = "vaurca_acanthognathus"
- myrmoteras
+ myrmoteras
name = "Myrmoteras Mandibles"
icon_state = "vaurca_myrmoteras"
@@ -4562,7 +4569,7 @@ Follow by example and make good judgement based on length which list to include
name = "Axiori Eyes"
icon_state = "skr_axiori_eyes"
body_parts = list(BP_HEAD)
- species_allowed = list(/datum/species/skrell, /datum/species/zombie/skrell)
+ species_allowed = list(/datum/species/skrell, /datum/species/zombie/skrell,/datum/species/zombie/skrell)
do_colouration = FALSE
skr_arms
@@ -4571,6 +4578,41 @@ Follow by example and make good judgement based on length which list to include
body_parts = list(BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND)
species_allowed = list(/datum/species/skrell,/datum/species/skrell/axiori,/datum/species/zombie/skrell)
+ skr_blotch_arms
+ name = "Skrell Arm Blotches"
+ icon = 'icons/mob/human_races/markings_skrell.dmi'
+ icon_state = "skr_blotch_arms"
+ body_parts = list(BP_L_ARM,BP_R_ARM)
+ species_allowed = list(/datum/species/skrell,/datum/species/skrell/axiori,/datum/species/zombie/skrell)
+
+ skr_blotch_leg
+ name = "Skrell Leg Blotches"
+ icon = 'icons/mob/human_races/markings_skrell.dmi'
+ icon_state = "skr_blotch_legs"
+ body_parts = list(BP_L_LEG,BP_R_LEG)
+ species_allowed = list(/datum/species/skrell,/datum/species/skrell/axiori,/datum/species/zombie/skrell)
+
+ skr_back_stripes
+ name = "Skrell Back Stripes"
+ icon = 'icons/mob/human_races/markings_skrell.dmi'
+ icon_state = "skr_back_stripes"
+ body_parts = list(BP_CHEST)
+ species_allowed = list(/datum/species/skrell,/datum/species/skrell/axiori,/datum/species/zombie/skrell)
+
+ skr_stomach
+ name = "Skrell Stomach"
+ icon = 'icons/mob/human_races/markings_skrell.dmi'
+ icon_state = "skr_stomach"
+ body_parts = list(BP_CHEST)
+ species_allowed = list(/datum/species/skrell,/datum/species/skrell/axiori,/datum/species/zombie/skrell)
+
+ skr_chin
+ name = "Skrell Chin"
+ icon = 'icons/mob/human_races/markings_skrell.dmi'
+ icon_state = "skr_chin"
+ body_parts = list(BP_HEAD)
+ species_allowed = list(/datum/species/skrell,/datum/species/skrell/axiori,/datum/species/zombie/skrell)
+
diona_leaves
name = "Diona Leaves"
icon = 'icons/mob/human_races/markings_diona.dmi'
diff --git a/code/modules/mob/abstract/observer/say.dm b/code/modules/mob/abstract/observer/say.dm
index 4c0225d1bb7..aabb0de9faa 100644
--- a/code/modules/mob/abstract/observer/say.dm
+++ b/code/modules/mob/abstract/observer/say.dm
@@ -1,4 +1,4 @@
-/mob/abstract/observer/say(var/message)
+/mob/abstract/observer/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if (!message)
return
diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm
index 7a033f70352..9690a5ac945 100644
--- a/code/modules/mob/language/language.dm
+++ b/code/modules/mob/language/language.dm
@@ -156,10 +156,12 @@
/datum/language/proc/check_special_condition(var/mob/other)
return 1
-/datum/language/proc/get_spoken_verb(var/msg_end, var/pre_end, var/singing = FALSE)
+/datum/language/proc/get_spoken_verb(var/msg_end, var/pre_end, var/singing = FALSE, var/whisper = FALSE)
var/chosen_verb = speech_verb
if(singing)
return pick(sing_verb)
+ if(whisper)
+ return pick(whisper_verb)
switch(msg_end)
if("!")
if(pre_end == "!" || pre_end == "?")
diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm
index b765abc3885..d3538605bac 100644
--- a/code/modules/mob/living/bot/bot.dm
+++ b/code/modules/mob/living/bot/bot.dm
@@ -161,10 +161,8 @@
return
return attack_hand(user)
-/mob/living/bot/say(var/message)
- var/verb = "beeps"
-
- ..(message, null, verb)
+/mob/living/bot/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
+ ..(message, null, "beeps")
/mob/living/bot/Collide(atom/A)
if(on && botcard && istype(A, /obj/machinery/door))
diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm
index 1dd1a48d3f0..185e7d87503 100644
--- a/code/modules/mob/living/carbon/brain/say.dm
+++ b/code/modules/mob/living/carbon/brain/say.dm
@@ -1,15 +1,14 @@
//TODO: Convert this over for languages.
-/mob/living/carbon/brain/say(var/message)
+/mob/living/carbon/brain/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if (silent)
return
if(!(container && istype(container, /obj/item/device/mmi)))
return //No MMI, can't speak, bucko./N
else
- var/datum/language/speaking = parse_language(message)
+ speaking = parse_language(message)
if(speaking)
message = copytext(message, 2+length(speaking.key))
- var/verb = "says"
var/ending = copytext(message, length(message))
var/pre_ending = copytext(message, length(message) - 1, length(message))
if (speaking)
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index f54a8006c48..b4ab24eb1f1 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -109,12 +109,12 @@
for it but just ignore it.
*/
-/mob/living/carbon/human/say_quote(var/message, var/datum/language/speaking = null, var/singing = FALSE)
+/mob/living/carbon/human/say_quote(var/message, var/datum/language/speaking = null, var/singing = FALSE, var/whisper = FALSE)
var/ending = copytext(message, length(message))
var/pre_ending = copytext(message, length(message) - 1, length(message))
if(speaking)
- . = speaking.get_spoken_verb(ending, pre_ending, singing)
+ . = speaking.get_spoken_verb(ending, pre_ending, singing, whisper)
else
. = ..()
@@ -161,9 +161,9 @@
return headsets[headsets[1]]
return null
-/mob/living/carbon/human/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio)
- if(paralysis || InStasis())
- whisper_say(message, speaking, alt_name)
+/mob/living/carbon/human/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper)
+ if(!whisper && (paralysis || InStasis()))
+ whisper(message, speaking)
return TRUE
switch(message_mode)
if("intercom")
@@ -218,8 +218,8 @@
if(R.talk_into(src,message,null,verb,speaking))
successful_radio += R
if("whisper")
- whisper_say(message, speaking, alt_name)
- return 1
+ whisper(message, speaking)
+ return TRUE
else if(message_mode)
var/obj/item/device/radio/R = get_radio()
if(R)
diff --git a/code/modules/mob/living/carbon/human/species/station/skrell/skrell.dm b/code/modules/mob/living/carbon/human/species/station/skrell/skrell.dm
index e517f7c51e8..28600ad9cc4 100644
--- a/code/modules/mob/living/carbon/human/species/station/skrell/skrell.dm
+++ b/code/modules/mob/living/carbon/human/species/station/skrell/skrell.dm
@@ -59,7 +59,6 @@
BP_KIDNEYS = /obj/item/organ/internal/kidneys/skrell,
BP_BRAIN = /obj/item/organ/internal/brain/skrell,
BP_STOMACH = /obj/item/organ/internal/stomach,
- BP_APPENDIX = /obj/item/organ/internal/appendix,
BP_EYES = /obj/item/organ/internal/eyes/skrell
)
diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm
deleted file mode 100644
index af1c6321500..00000000000
--- a/code/modules/mob/living/carbon/human/whisper.dm
+++ /dev/null
@@ -1,159 +0,0 @@
-//Lallander was here
-/mob/living/carbon/human/whisper(message as text)
- var/alt_name = ""
-
- if(say_disabled) //This is here to try to identify lag problems
- to_chat(usr, "Speech is currently admin-disabled.")
- return
-
- message = sanitize(message)
-
- if (client && client.handle_spam_prevention(message,MUTE_IC))
- return
-
- if (src.stat == 2)
- return src.say_dead(message)
-
- if (src.stat)
- return
-
- if(name != GetVoice())
- alt_name = "(as [get_id_name("Unknown")])"
-
- //parse the language code and consume it
- var/datum/language/speaking = parse_language(message)
- if (speaking)
- message = copytext(message,2+length(speaking.key))
-
- whisper_say(message, speaking, alt_name)
-
-
-//This is used by both the whisper verb and human/say() to handle whispering
-/mob/living/carbon/human/proc/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/whisper_text = "whispers")
-
- if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
- to_chat(src, "You're muzzled and cannot speak!")
- return
-
- var/message_range = 1
- var/eavesdropping_range = 2
- var/watching_range = 5
- var/italics = 1
-
- var/not_heard //the message displayed to people who could not hear the whispering
- if(speaking)
- if(speaking.whisper_verb)
- whisper_text = pick(speaking.whisper_verb)
- not_heard = "[whisper_text] something"
- else
- var/adverb = pick("quietly", "softly")
- whisper_text = "[speaking.speech_verb] [adverb]"
- not_heard = "[speaking.speech_verb] something [adverb]"
- else
- not_heard = "[whisper_text] something"
-
- message = capitalize(trim(message))
-
- if(speech_problem_flag)
- var/list/handle_r = handle_speech_problems(message)
- message = handle_r[1]
- whisper_text = handle_r[2]
- var/adverb = pick("quietly", "softly")
- whisper_text = "[whisper_text] [adverb]"
-
- speech_problem_flag = handle_r[3]
-
- if(!message || message=="")
- return
-
- log_whisper("[key_name(src)] : ([get_lang_name(speaking)]) [message]",ckey=key_name(src))
-
- //looks like this only appears in whisper. Should it be elsewhere as well? Maybe handle_speech_problems?
- var/voice_sub
- if(istype(back,/obj/item/rig))
- var/obj/item/rig/rig = back
- // todo: fix this shit
- if(rig.speech && rig.speech.voice_holder && rig.speech.voice_holder.active && rig.speech.voice_holder.voice)
- voice_sub = rig.speech.voice_holder.voice
- else
- for(var/obj/item/gear in list(wear_mask,wear_suit,head))
- if(!gear)
- continue
- var/obj/item/voice_changer/changer = locate() in gear
- if(changer && changer.active && changer.voice)
- voice_sub = changer.voice
-
- if(voice_sub == "Unknown")
- if(copytext(message, 1, 2) != "*")
- var/list/temp_message = text2list(message, " ")
- var/list/pick_list = list()
- for(var/i = 1, i <= temp_message.len, i++)
- pick_list += i
- for(var/i=1, i <= abs(temp_message.len/3), i++)
- var/H = pick(pick_list)
- if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
- temp_message[H] = ninjaspeak(temp_message[H])
- pick_list -= H
- message = jointext(temp_message, " ")
- message = replacetext(message, "o", "¤")
- message = replacetext(message, "p", "ž")
- message = replacetext(message, "l", "£")
- message = replacetext(message, "s", "§")
- message = replacetext(message, "u", "µ")
- message = replacetext(message, "b", "ß")
-
- var/list/listening = hearers(message_range, src)
- listening |= src
-
- //ghosts
- for (var/mob/M in dead_mob_list) //does this include players who joined as observers as well?
- if (!(M.client))
- continue
- if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
- listening |= M
-
- //Pass whispers on to anything inside the immediate listeners.
- for(var/mob/L in listening)
- for(var/mob/C in L.contents)
- if(istype(C,/mob/living))
- listening += C
-
- //pass on the message to objects that can hear us.
- for (var/obj/O in view(message_range, src))
- spawn (0)
- if (O)
- O.hear_talk(src, message, whisper_text, speaking)
-
- var/list/eavesdropping = hearers(eavesdropping_range, src)
- eavesdropping -= src
- eavesdropping -= listening
-
- var/list/watching = hearers(watching_range, src)
- watching -= src
- watching -= listening
- watching -= eavesdropping
-
- //now mobs
-
- var/list/listening_clients = list() // The clients we're going to show the speech bubble to.
-
- for(var/mob/M in listening)
- M.hear_say(message, whisper_text, speaking, alt_name, italics, src)
- if (M.client)
- listening_clients += M.client
-
- if (eavesdropping.len)
- var/new_message = stars(message) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less.
- for(var/mob/M in eavesdropping)
- M.hear_say(new_message, whisper_text, speaking, alt_name, italics, src)
- if (M.client)
- listening_clients += M.client
-
- var/speech_bubble_test = say_test(message)
- var/image/speech_bubble = image(get_talk_bubble(),src,"h[speech_bubble_test]")
- INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, speech_bubble, listening_clients, 30)
-
- if (watching.len)
- var/rendered = "[src.name] [not_heard]."
- for (var/mob/M in watching)
- M.show_message(rendered, 2)
diff --git a/code/modules/mob/living/carbon/slime/say.dm b/code/modules/mob/living/carbon/slime/say.dm
index 35b3a763e90..0821a8d241d 100644
--- a/code/modules/mob/living/carbon/slime/say.dm
+++ b/code/modules/mob/living/carbon/slime/say.dm
@@ -1,6 +1,5 @@
-/mob/living/carbon/slime/say(var/message)
-
- var/verb = say_quote(message)
+/mob/living/carbon/slime/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
+ verb = say_quote(message)
if(copytext(message,1,2) == "*")
return emote(copytext(message,2))
diff --git a/code/modules/mob/living/parasite/meme.dm b/code/modules/mob/living/parasite/meme.dm
index d2da60c77a0..fb22a025852 100644
--- a/code/modules/mob/living/parasite/meme.dm
+++ b/code/modules/mob/living/parasite/meme.dm
@@ -103,7 +103,7 @@ var/controlling
qdel(src)
// When a meme speaks, it speaks through its host
-/mob/living/parasite/meme/say(message as text)
+/mob/living/parasite/meme/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(dormant)
to_chat(src, "You are dormant! ")
return
diff --git a/code/modules/mob/living/parasite/meme_captive.dm b/code/modules/mob/living/parasite/meme_captive.dm
index 67415f310ab..daafff3001c 100644
--- a/code/modules/mob/living/parasite/meme_captive.dm
+++ b/code/modules/mob/living/parasite/meme_captive.dm
@@ -3,7 +3,7 @@
real_name = "host brain"
universal_understand = 1
-/mob/living/parasite/captive_brain/say(var/message)
+/mob/living/parasite/captive_brain/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(istype(src.loc,/mob/living/parasite/meme))
if (!message)
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 4a5868d5be6..2929c382b1d 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -124,12 +124,15 @@ proc/get_radio_key_from_channel(var/channel)
returns[4] = world.view
return returns
-/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio)
+/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper)
if(message_mode == "intercom")
for(var/obj/item/device/radio/intercom/I in view(1, null))
used_radios += I
if(I.talk_into(src, message, verb, speaking))
successful_radio += I
+ if(message_mode == "whisper" && !whisper)
+ whisper(message, speaking)
+ return TRUE
return 0
/mob/living/proc/handle_speech_sound()
@@ -153,7 +156,7 @@ proc/get_radio_key_from_channel(var/channel)
return FONT_SIZE_LARGE
return null
-/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR)
+/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(stat)
if(stat == DEAD)
return say_dead(message)
@@ -177,13 +180,15 @@ proc/get_radio_key_from_channel(var/channel)
message = trim(message)
message = formalize_text(message)
+ var/had_speaking = !!speaking
//parse the language code and consume it
if(!speaking || speaking.always_parse_language)
speaking = parse_language(message)
- if(speaking)
- message = copytext(message,2+length(speaking.key))
- else
- speaking = get_default_language()
+ if(!had_speaking)
+ if(speaking)
+ message = copytext(message,2+length(speaking.key))
+ else
+ speaking = get_default_language()
if(speaking)
var/list/speech_mod = speaking.handle_message_mode(message_mode)
@@ -205,7 +210,7 @@ proc/get_radio_key_from_channel(var/channel)
speaking.broadcast(src,trim(message))
return 1
- verb = say_quote(message, speaking, is_singing)
+ verb = say_quote(message, speaking, is_singing, whisper)
if(is_muzzled())
to_chat(src, "You're muzzled and cannot speak!")
@@ -240,7 +245,7 @@ proc/get_radio_key_from_channel(var/channel)
var/list/obj/item/used_radios = new
var/list/successful_radio = new // passes a list because standard vars don't work when passed
- if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio))
+ if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper))
return 1
var/list/handle_v = handle_speech_sound()
@@ -269,6 +274,10 @@ proc/get_radio_key_from_channel(var/channel)
var/list/listening_obj = list()
var/turf/T = get_turf(src)
+ if(whisper)
+ message_range = 1
+ italics = TRUE
+
if(T)
if(!speaking || !(speaking.flags & PRESSUREPROOF))
//make sure the air can transmit speech - speaker's side
@@ -305,7 +314,11 @@ proc/get_radio_key_from_channel(var/channel)
if(mind)
mind.last_words = message
- log_say("[key_name(src)] : ([get_lang_name(speaking)]) [message]",ckey=key_name(src))
+ if(whisper)
+ log_whisper("[key_name(src)] : ([get_lang_name(speaking)]) [message]",ckey=key_name(src))
+ else
+ log_say("[key_name(src)] : ([get_lang_name(speaking)]) [message]",ckey=key_name(src))
+
return 1
/mob/living/proc/do_animate_chat(var/message, var/datum/language/language, var/small, var/list/show_to, var/duration)
diff --git a/code/modules/mob/living/silicon/pai/say.dm b/code/modules/mob/living/silicon/pai/say.dm
index ffbfbc7b04b..f2d8a1c62d1 100644
--- a/code/modules/mob/living/silicon/pai/say.dm
+++ b/code/modules/mob/living/silicon/pai/say.dm
@@ -1,5 +1,5 @@
-/mob/living/silicon/pai/say(var/msg)
+/mob/living/silicon/pai/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(silence_time)
to_chat(src, "Communication circuits remain uninitialized.")
- else
- ..(msg)
\ No newline at end of file
+ return
+ return ..()
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index 76778c89380..3712740cf5c 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -1,6 +1,3 @@
-/mob/living/silicon/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
- log_say("[key_name(src)] : [message]",ckey=key_name(src))
-
/mob/living/silicon/robot/handle_speech_problems(var/message, var/verb, var/message_mode)
var/speech_problem_flag = FALSE
//Handle gibberish when components are damaged
@@ -23,22 +20,28 @@
returns[4] = world.view
return returns
-/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
- ..()
+/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper)
+ if(message_mode == "whisper" && !whisper)
+ whisper(message, speaking)
+ return TRUE
if(message_mode)
if(!is_component_functioning("radio"))
to_chat(src, SPAN_WARNING("Your radio isn't functional at this time."))
return 0
if(message_mode == "general")
message_mode = null
+ log_say("[key_name(src)] : [message]",ckey=key_name(src))
return common_radio.talk_into(src, message, message_mode, verb, speaking)
/mob/living/silicon/robot/drone/handle_message_mode()
return null
-/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
- ..()
+/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper)
+ if(message_mode == "whisper" && !whisper)
+ whisper(message, speaking)
+ return TRUE
if(message_mode == "department")
+ log_say("[key_name(src)] : [message]",ckey=key_name(src))
return holopad_talk(message, verb, speaking)
else if(message_mode)
if(ai_radio.disabledAi || ai_restore_power_routine || stat)
@@ -46,16 +49,24 @@
return FALSE
if(message_mode == "general")
message_mode = null
+ log_say("[key_name(src)] : [message]",ckey=key_name(src))
return ai_radio.talk_into(src, message, message_mode, verb, speaking)
-/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
- ..()
+/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper)
if(message_mode)
+ if(message_mode == "whisper" && !whisper)
+ whisper(message, speaking)
+ return TRUE
if(message_mode == "general")
message_mode = null
+ log_say("[key_name(src)] : [message]",ckey=key_name(src))
return radio.talk_into(src, message, message_mode, verb, speaking)
-/mob/living/silicon/say_quote(var/text)
+/mob/living/silicon/say_quote(var/text, var/datum/language/speaking = null, var/singing = FALSE, var/whisper = FALSE)
+ if(singing)
+ return "sings"
+ if(whisper)
+ return "whispers"
var/ending = copytext(text, length(text))
if(ending == "?")
return speak_query
diff --git a/code/modules/mob/living/simple_animal/borer/borer_captive.dm b/code/modules/mob/living/simple_animal/borer/borer_captive.dm
index bb2d50174d5..363378dd789 100644
--- a/code/modules/mob/living/simple_animal/borer/borer_captive.dm
+++ b/code/modules/mob/living/simple_animal/borer/borer_captive.dm
@@ -6,7 +6,7 @@
var/datum/progressbar/resist_bar
var/resist_start_time = 0
-/mob/living/captive_brain/say(var/message)
+/mob/living/captive_brain/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(istype(src.loc,/mob/living/simple_animal/borer))
if(!message)
return
diff --git a/code/modules/mob/living/simple_animal/borer/say.dm b/code/modules/mob/living/simple_animal/borer/say.dm
index 8f9af1a43c2..dfcf844bcde 100644
--- a/code/modules/mob/living/simple_animal/borer/say.dm
+++ b/code/modules/mob/living/simple_animal/borer/say.dm
@@ -1,4 +1,4 @@
-/mob/living/simple_animal/borer/say(var/message)
+/mob/living/simple_animal/borer/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
message = capitalize(message)
if(!message)
diff --git a/code/modules/mob/living/simple_animal/constructs/constructs/cult_construct.dm b/code/modules/mob/living/simple_animal/constructs/constructs/cult_construct.dm
index 725ec8c9575..1502cef27f1 100644
--- a/code/modules/mob/living/simple_animal/constructs/constructs/cult_construct.dm
+++ b/code/modules/mob/living/simple_animal/constructs/constructs/cult_construct.dm
@@ -44,6 +44,8 @@
var/health_prefix = ""
appearance_flags = NO_CLIENT_COLOR|KEEP_TOGETHER
+ psi_pingable = FALSE
+
/mob/living/simple_animal/construct/cultify()
return
diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
index 77985304bf5..0b36c275454 100644
--- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
@@ -46,6 +46,8 @@
speak_emote = list("beeps","clicks","chirps")
universal_understand = TRUE
+ psi_pingable = FALSE
+
/mob/living/simple_animal/spiderbot/Initialize()
. = ..()
add_language(LANGUAGE_TCB)
@@ -314,8 +316,12 @@
/mob/living/simple_animal/spiderbot/get_bullet_impact_effect_type(var/def_zone)
return BULLET_IMPACT_METAL
-/mob/living/simple_animal/spiderbot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
+/mob/living/simple_animal/spiderbot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper)
switch(message_mode)
+ if("whisper")
+ if(!whisper)
+ whisper(message, speaking)
+ return TRUE
if("headset")
radio.talk_into(src, message, null, verb, speaking)
used_radios += radio
@@ -345,4 +351,4 @@
/mob/living/simple_animal/spiderbot/ai/Initialize()
. = ..()
- internal_id.access = get_all_station_access()
\ No newline at end of file
+ internal_id.access = get_all_station_access()
diff --git a/code/modules/mob/living/simple_animal/hostile/commanded/ives.dm b/code/modules/mob/living/simple_animal/hostile/commanded/ives.dm
index 28626622231..e2521902c9c 100644
--- a/code/modules/mob/living/simple_animal/hostile/commanded/ives.dm
+++ b/code/modules/mob/living/simple_animal/hostile/commanded/ives.dm
@@ -49,6 +49,8 @@
destroy_surroundings = FALSE
attack_emote = "blares a tiny siren"
+ psi_pingable = FALSE
+
/mob/living/simple_animal/hostile/commanded/baby_harvester/get_bullet_impact_effect_type(var/def_zone)
return BULLET_IMPACT_METAL
diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm
index 8982049efff..99237d206f6 100644
--- a/code/modules/mob/living/simple_animal/hostile/faithless.dm
+++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm
@@ -38,6 +38,8 @@
flying = TRUE
+ psi_pingable = FALSE
+
/mob/living/simple_animal/hostile/faithless/Allow_Spacemove(var/check_drift = 0)
return 1
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot.dm
index 30f55b7a096..38443ae17ce 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot.dm
@@ -32,6 +32,7 @@
pass_flags = PASSTABLE
attack_emote = "focuses on"
var/mob/living/simple_animal/hostile/hivebotbeacon/linked_parent = null
+ psi_pingable = FALSE
/mob/living/simple_animal/hostile/hivebot/do_animate_chat(var/message, var/datum/language/language, var/small, var/list/show_to, var/duration, var/list/message_override)
INVOKE_ASYNC(src, /atom/movable/proc/animate_chat, message, language, small, show_to, duration)
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_beacon.dm b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_beacon.dm
index 7783c78adf3..d149a04858d 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_beacon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_beacon.dm
@@ -48,6 +48,7 @@
var/list/close_destinations = list()
var/area/latest_area
attack_emote = "focuses on"
+ psi_pingable = FALSE
/mob/living/simple_animal/hostile/hivebotbeacon/incendiary
projectiletype = /obj/item/projectile/beam/hivebot/incendiary
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_harvester.dm b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_harvester.dm
index 99b24c93dc5..484add5d94b 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_harvester.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebots/hivebot_harvester.dm
@@ -42,6 +42,8 @@
mob_bump_flag = HEAVY
mob_swap_flags = ~HEAVY
mob_push_flags = 0
+
+ psi_pingable = FALSE
/mob/living/simple_animal/hostile/retaliate/hivebotharvester/Initialize(mapload,mob/living/simple_animal/hostile/hivebot/hivebotbeacon)
if(hivebotbeacon)
diff --git a/code/modules/mob/living/simple_animal/hostile/icarus_drone.dm b/code/modules/mob/living/simple_animal/hostile/icarus_drone.dm
index c29dd613f31..34f536a7f07 100644
--- a/code/modules/mob/living/simple_animal/hostile/icarus_drone.dm
+++ b/code/modules/mob/living/simple_animal/hostile/icarus_drone.dm
@@ -58,6 +58,8 @@
see_in_dark = 8
see_invisible = SEE_INVISIBLE_NOLIGHTING
+ psi_pingable = FALSE
+
/mob/living/simple_animal/hostile/icarus_drone/Initialize()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/krampus.dm b/code/modules/mob/living/simple_animal/hostile/krampus.dm
index ad6719862c6..1cc67cfc12d 100644
--- a/code/modules/mob/living/simple_animal/hostile/krampus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/krampus.dm
@@ -43,6 +43,7 @@
var/is_punishing = FALSE
+ psi_pingable = FALSE
/mob/living/simple_animal/hostile/krampus/death(gibbed)
..()
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/cavern.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/cavern.dm
index 4c5ef98db8b..24070eb5f28 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/cavern.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/cavern.dm
@@ -110,6 +110,7 @@
light_range = 10
light_wedge = LIGHT_WIDE
see_in_dark = 8
+ psi_pingable = FALSE
faction = "sol"
diff --git a/code/modules/mob/living/simple_animal/hostile/rogue_maint_drone.dm b/code/modules/mob/living/simple_animal/hostile/rogue_maint_drone.dm
index af50c12a5e4..eea15669683 100644
--- a/code/modules/mob/living/simple_animal/hostile/rogue_maint_drone.dm
+++ b/code/modules/mob/living/simple_animal/hostile/rogue_maint_drone.dm
@@ -20,6 +20,8 @@
mob_size = MOB_TINY
var/image/eye_overlay
+ psi_pingable = FALSE
+
/mob/living/simple_animal/hostile/rogue_drone/Initialize()
. = ..()
name = "[initial(name)] ([rand(100, 999)])"
diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm
index 91b9dbbe44e..293d280dee5 100644
--- a/code/modules/mob/living/simple_animal/hostile/tree.dm
+++ b/code/modules/mob/living/simple_animal/hostile/tree.dm
@@ -39,6 +39,8 @@
faction = "carp"
+ psi_pingable = FALSE
+
/mob/living/simple_animal/hostile/tree/FindTarget()
. = ..()
if(.)
diff --git a/code/modules/mob/living/simple_animal/hostile/vannatusk.dm b/code/modules/mob/living/simple_animal/hostile/vannatusk.dm
index 88489f6f644..2ad2ea9ba3f 100644
--- a/code/modules/mob/living/simple_animal/hostile/vannatusk.dm
+++ b/code/modules/mob/living/simple_animal/hostile/vannatusk.dm
@@ -42,6 +42,8 @@
var/crystal_harvested = FALSE
+ psi_pingable = FALSE
+
/mob/living/simple_animal/hostile/vannatusk/Initialize()
. = ..()
set_light(1.2, 3, LIGHT_COLOR_BLUE)
diff --git a/code/modules/mob/living/simple_animal/hostile/viscerator.dm b/code/modules/mob/living/simple_animal/hostile/viscerator.dm
index 3cd9fd57397..52cb96a1521 100644
--- a/code/modules/mob/living/simple_animal/hostile/viscerator.dm
+++ b/code/modules/mob/living/simple_animal/hostile/viscerator.dm
@@ -30,6 +30,8 @@
flying = TRUE
attack_emote = "buzzes at"
+ psi_pingable = FALSE
+
/mob/living/simple_animal/hostile/viscerator/death()
..(null,"is smashed into pieces!")
var/T = get_turf(src)
diff --git a/code/modules/mob/living/simple_animal/illusion.dm b/code/modules/mob/living/simple_animal/illusion.dm
index 8cf3685e1cc..e4f0f772dd3 100644
--- a/code/modules/mob/living/simple_animal/illusion.dm
+++ b/code/modules/mob/living/simple_animal/illusion.dm
@@ -10,6 +10,8 @@
var/atom/movable/copying = null // The thing we're trying to look like.
var/realistic = FALSE // If true, things like bullets and weapons will hit it, to be a bit more convincing from a distance.
+ psi_pingable = FALSE
+
/mob/living/simple_animal/illusion/update_icon() // We don't want the appearance changing AT ALL unless by copy_appearance().
return
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 2e1579eac2b..f9714bf1943 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -694,12 +694,11 @@
available_channels = list(":e")
. = ..()
-/mob/living/simple_animal/parrot/say(var/message)
+/mob/living/simple_animal/parrot/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(stat)
return
- var/verb = "says"
if(speak_emote.len)
verb = pick(speak_emote)
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index 9afbfe0a8c8..22914d103e1 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -32,6 +32,8 @@
appearance_flags = NO_CLIENT_COLOR|KEEP_TOGETHER
var/obj/item/residue = /obj/item/ectoplasm
+ psi_pingable = FALSE
+
/mob/living/simple_animal/shade/cultify()
return
@@ -208,7 +210,7 @@
heard_dying_message = 0
to_chat(src, "The soothing echoes of life reinvigorate you.")
-/mob/living/simple_animal/shade/bluespace/say(var/message)
+/mob/living/simple_animal/shade/bluespace/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(!possessive)
var/list/words_in_memory = dd_text2List(last_message_heard, " ")
var/list/words_in_message = dd_text2List(message, " ")
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 7f09dce3e3d..6ba16b72cf1 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -134,6 +134,8 @@
var/list/butchering_products //if anything else is created when butchering this creature, like bones and leather
+ var/psi_pingable = TRUE
+
/mob/living/simple_animal/proc/update_nutrition_stats()
nutrition_step = mob_size * 0.03 * metabolic_factor
@@ -752,8 +754,7 @@
/mob/living/simple_animal/proc/reset_sound_time()
sound_time = TRUE
-/mob/living/simple_animal/say(var/message)
- var/verb = "says"
+/mob/living/simple_animal/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(speak_emote.len)
verb = pick(speak_emote)
diff --git a/code/modules/mob/living/whisper.dm b/code/modules/mob/living/whisper.dm
new file mode 100644
index 00000000000..23b3550ce35
--- /dev/null
+++ b/code/modules/mob/living/whisper.dm
@@ -0,0 +1,75 @@
+/mob/living/verb/whisper_verb(message as text)
+ set name = "Whisper"
+ set category = "IC"
+
+ if(say_disabled)
+ to_chat(usr, SPAN_WARNING("Speech is currently admin-disabled."))
+ return
+
+ message = sanitize(message)
+ message = formalize_text(message)
+
+ set_typing_indicator(0)
+
+ if(client.handle_spam_prevention(message, MUTE_IC))
+ return
+
+ whisper(message)
+
+/mob/living/proc/whisper(var/message, var/datum/language/speaking)
+ if(is_muzzled())
+ to_chat(src, SPAN_DANGER("You're muzzled and cannot speak!"))
+ return
+
+ speaking = speaking ? speaking : parse_language(message)
+
+ var/message_range = 1
+ var/eavesdropping_range = 2
+ var/watching_range = 5
+
+ var/whisper_text = "whispers"
+ var/not_heard = "[whisper_text] something"
+ if(speaking)
+ if(speaking.whisper_verb)
+ whisper_text = pick(speaking.whisper_verb)
+ not_heard = "[whisper_text] something"
+ else
+ var/adverb = pick("quietly", "softly")
+ whisper_text = "[speaking.speech_verb] [adverb]"
+ not_heard = "[speaking.speech_verb] something [adverb]"
+
+ var/list/listening = list(src)
+
+ //ghosts
+ for(var/mob/M in dead_mob_list)
+ if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
+ listening |= M
+
+ //Pass whispers on to anything inside the immediate listeners.
+ for(var/mob/L in listening)
+ for(var/mob/living/C in L.contents)
+ listening += C
+
+ var/list/eavesdropping = list()
+ var/list/watching = list()
+
+ var/list/all_in_range = hearers(watching_range, src)
+ for(var/mob/M as anything in all_in_range)
+ if(get_dist(src, M) <= message_range)
+ listening |= M
+ else if(get_dist(src, M) <= eavesdropping_range)
+ eavesdropping += M
+ else if(get_dist(src, M) <= watching_range)
+ watching += M
+
+ if(length(eavesdropping))
+ var/new_message = stars(message)
+ for(var/mob/M in eavesdropping)
+ M.hear_say(new_message, "whispers", speaking, "", TRUE, src)
+
+ if(length(watching))
+ var/rendered = "[src.name] [not_heard]."
+ for (var/mob/M in watching)
+ M.show_message(rendered, 2)
+
+ say(message, speaking, whisper_text, whisper = TRUE)
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index b4e904e1292..823c3ec27d9 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -1,9 +1,4 @@
-/mob/proc/say()
- return
-
-/mob/verb/whisper()
- set name = "Whisper"
- set category = "IC"
+/mob/proc/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
return
/mob/verb/say_verb(message as text)
@@ -11,7 +6,7 @@
set category = "IC"
if(say_disabled) //This is here to try to identify lag problems
- to_chat(usr, "Speech is currently admin-disabled.")
+ to_chat(usr, SPAN_WARNING("Speech is currently admin-disabled."))
return
message = sanitize(message)
@@ -101,10 +96,12 @@
for it but just ignore it.
*/
-/mob/proc/say_quote(var/message, var/datum/language/speaking = null, var/singing = FALSE)
+/mob/proc/say_quote(var/message, var/datum/language/speaking = null, var/singing = FALSE, var/whisper = FALSE)
. = "says"
if(singing)
return "sings"
+ if(whisper)
+ return "whispers"
var/ending = copytext(message, length(message))
var/pre_ending = copytext(message, length(message) - 1, length(message))
if(ending == "!")
diff --git a/code/modules/modular_computers/file_system/programs/command/comm.dm b/code/modules/modular_computers/file_system/programs/command/comm.dm
index 0804c8ded66..8b7209ad391 100644
--- a/code/modules/modular_computers/file_system/programs/command/comm.dm
+++ b/code/modules/modular_computers/file_system/programs/command/comm.dm
@@ -391,7 +391,7 @@ Command action procs
return FALSE
//Returns 1 if called 0 if not
-/proc/call_shuttle_proc(var/mob/user)
+/proc/call_shuttle_proc(var/mob/user, var/emergency = FALSE)
if((!(ROUND_IS_STARTED) || !evacuation_controller))
return FALSE
@@ -414,8 +414,8 @@ Command action procs
to_chat(user, "An evacuation is already underway.")
return
- if(evacuation_controller.call_evacuation(user))
- log_and_message_admins("[user? key_name(user) : "Autotransfer"] has called the shuttle.")
+ if(evacuation_controller.call_evacuation(user, emergency))
+ log_and_message_admins("[user? key_name(user) : "Autotransfer"] has called a shuttle.")
return TRUE
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index 8ae7bb0ba4f..7635757ecb0 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -89,7 +89,6 @@ VUEUI_MONITOR_VARS(/obj/machinery/photocopier, photocopiermonitor)
p.desc += "Copied by [tempAI.name]"
else
p.desc += " - Copied by [tempAI.name]"
- toner -= 5
sleep(15)
SSvueui.check_uis_for_change(src)
@@ -173,7 +172,10 @@ VUEUI_MONITOR_VARS(/obj/machinery/photocopier, photocopiermonitor)
info += copied
info += ""//
pname = copy.name // -- Doohl
- c.color = "#f0f0f0"
+ if(istype(copy, /obj/item/paper/business_card))
+ c.color = copy.color
+ else
+ c.color = "#f0f0f0"
c.fields = copy.fields
c.stamps = copy.stamps
c.stamped = copy.stamped
@@ -204,7 +206,9 @@ VUEUI_MONITOR_VARS(/obj/machinery/photocopier, photocopiermonitor)
c.set_content_unsafe(pname, info)
if (print)
if(target.type == /obj/machinery/photocopier)
+ var/obj/machinery/photocopier/T = target
flick("photocopier_print", target)
+ --T.toner
target.print(c, use_sound, 'sound/bureaucracy/print.ogg', delay)
return c
@@ -229,6 +233,11 @@ VUEUI_MONITOR_VARS(/obj/machinery/photocopier, photocopiermonitor)
if(target.type == /obj/machinery/photocopier)
flick("photocopier_notoner", target)
playsound(target.loc, 'sound/machines/buzz-two.ogg', 75, 1)
+ if(target.type == /obj/machinery/photocopier)
+ var/obj/machinery/photocopier/T = target
+ T.toner -= 5
+ flick("photocopier_print", target)
+ playsound(target.loc, 'sound/bureaucracy/print.ogg', 75, 1)
return p
//If need_toner is 0, the copies will still be lightened when low on toner, however it will not be prevented from printing. TODO: Implement print queues for fax machines and get rid of need_toner
@@ -239,7 +248,9 @@ VUEUI_MONITOR_VARS(/obj/machinery/photocopier, photocopiermonitor)
toner = 0
target.visible_message(SPAN_NOTICE("A red light on \the [target] flashes, indicating that it is out of toner."))
if(target.type == /obj/machinery/photocopier)
+ var/obj/machinery/photocopier/T = target
flick("photocopier_notoner", target)
+ --T.toner
playsound(target.loc, 'sound/machines/buzz-two.ogg', 75, 1)
break
diff --git a/code/modules/psionics/faculties/coercion.dm b/code/modules/psionics/faculties/coercion.dm
index 97e54d5b526..eb1cc97c84d 100644
--- a/code/modules/psionics/faculties/coercion.dm
+++ b/code/modules/psionics/faculties/coercion.dm
@@ -75,9 +75,10 @@
else
to_chat(user, SPAN_NOTICE("You dip your mentality into the surface layer of \the [target]'s mind, seeking an answer: [question]"))
to_chat(target, SPAN_NOTICE("Your mind is compelled to answer: [question]"))
- var/answer = sanitize(input(target, question, "Read Mind") as null|text)
+ var/answer = sanitize(input(target, "[question]\nYou have 25 seconds to type a response", "Read Mind") as null|text)
if(!answer || world.time > started_mindread + 25 SECONDS || user.stat != CONSCIOUS)
to_chat(user, SPAN_NOTICE("You receive nothing useful from \the [target]."))
+ to_chat(target, SPAN_NOTICE("Your mind blanks out momentarily."))
else
to_chat(user, SPAN_NOTICE("You skim thoughts from the surface of \the [target]'s mind: [answer]"))
msg_admin_attack("[key_name(user)] read mind of [key_name(target)] with question \"[question]\" and [answer?"got answer \"[answer]\".":"got no answer."]")
@@ -301,7 +302,7 @@
var/turf/T = get_turf(L)
if(!T || L == user || L.stat == DEAD || L.invisibility == INVISIBILITY_LEVEL_TWO)
continue
- if(L.is_psi_blocked())
+ if(!L.is_psi_pingable())
continue
var/image/ping_image = image(icon = 'icons/effects/effects.dmi', icon_state = "sonar_ping", loc = our_turf, layer = OBFUSCATION_LAYER + 0.1)
pixel_shift_to_turf(ping_image, our_turf, T)
diff --git a/code/modules/psionics/mob/mob_helpers.dm b/code/modules/psionics/mob/mob_helpers.dm
index bcd6958778e..0d7393cc0f2 100644
--- a/code/modules/psionics/mob/mob_helpers.dm
+++ b/code/modules/psionics/mob/mob_helpers.dm
@@ -19,4 +19,10 @@
for (var/obj/item/implant/mindshield/I in src)
if (I.implanted)
return SPAN_WARNING("[src]'s mind is inaccessible, like hitting a brick wall.")
- return FALSE
\ No newline at end of file
+ return FALSE
+
+/mob/living/proc/is_psi_pingable()
+ return !is_psi_blocked()
+
+/mob/living/simple_animal/is_psi_pingable()
+ return psi_pingable
diff --git a/code/modules/shareddream/brainghost.dm b/code/modules/shareddream/brainghost.dm
index cbe3adf066e..0852b95c608 100644
--- a/code/modules/shareddream/brainghost.dm
+++ b/code/modules/shareddream/brainghost.dm
@@ -58,7 +58,7 @@
if(body.stat == DEAD) // Body is dead, and won't get a life tick.
body.handle_shared_dreaming()
-/mob/living/brain_ghost/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="")
+/mob/living/brain_ghost/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(!istype(body) || body.stat!=UNCONSCIOUS)
return
if(prob(20)) // 1/5 chance to mumble out anything you say in the dream.
diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm
index 0f5882dea9d..e2878b1425c 100644
--- a/code/modules/shuttles/shuttle_emergency.dm
+++ b/code/modules/shuttles/shuttle_emergency.dm
@@ -27,8 +27,6 @@
/datum/shuttle/autodock/ferry/emergency/long_jump(var/obj/effect/shuttle_landmark/destination, var/obj/effect/shuttle_landmark/interim, var/travel_time)
..(destination, interim, emergency_controller.get_long_jump_time(), direction)
- if(destination == waypoint_offsite)
- priority_announcement.Announce(replacetext(replacetext((emergency_controller.emergency_evacuation ? current_map.emergency_shuttle_leaving_dock : current_map.shuttle_leaving_dock), "%dock%", "[current_map.dock_name]"), "%ETA%", "[round(emergency_controller.get_eta()/60,1)] minute\s"))
/datum/shuttle/autodock/ferry/emergency/shuttle_moved()
if(next_location != waypoint_station)
diff --git a/code/modules/spell_system/spells/spell_code.dm b/code/modules/spell_system/spells/spell_code.dm
index 92b5c997944..ed7b31cef48 100644
--- a/code/modules/spell_system/spells/spell_code.dm
+++ b/code/modules/spell_system/spells/spell_code.dm
@@ -262,7 +262,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
return 0
return 1
-/spell/proc/invocation(mob/user = usr, var/list/targets) //spelling the spell out and setting it on recharge/reducing charges amount
+/spell/proc/invocation(mob/living/user = usr, var/list/targets) //spelling the spell out and setting it on recharge/reducing charges amount
switch(invocation_type)
if(SpI_SHOUT)
@@ -353,4 +353,4 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
if(!user || (!(spell_flags & (STATALLOWED|GHOSTCAST)) && user.stat != originalstat) || !(user.loc == Location))
return 0
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index cec6208a450..5a449edacf2 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -214,7 +214,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(SPAN_NOTICE("[user] has reattached the [affected.tendon_name] in [target]'s [affected.name] with \the [tool]."), \
SPAN_NOTICE("You have reattached the [affected.tendon_name] in [target]'s [affected.name] with \the [tool]."))
- affected.tendon.heal()
+ affected.tendon.rejuvenate()
affected.update_damages()
/decl/surgery_step/fix_tendon/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
diff --git a/html/changelog.html b/html/changelog.html
index 1dd780756bc..46daac086b6 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -35,6 +35,106 @@
-->