diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index 998b712828..1fe5d43a59 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -18,6 +18,8 @@
var/mind=null
var/languages=null
var/list/flavor=null
+ var/gender = null
+ var/list/body_descriptors = null
var/list/genetic_modifiers = list() // Modifiers with the MODIFIER_GENETIC flag are saved. Note that only the type is saved, not an instance.
/datum/dna2/record/proc/GetData()
@@ -706,7 +708,10 @@
databuf.types = DNA2_BUF_UE
databuf.dna = src.connected.occupant.dna.Clone()
if(ishuman(connected.occupant))
- databuf.dna.real_name=connected.occupant.dna.real_name
+ var/mob/living/carbon/human/H = connected.occupant
+ databuf.dna.real_name = H.dna.real_name
+ databuf.gender = H.gender
+ databuf.body_descriptors = H.descriptors
databuf.name = "Unique Identifier"
src.buffers[bufferId] = databuf
return 1
@@ -717,7 +722,10 @@
databuf.types = DNA2_BUF_UI|DNA2_BUF_UE
databuf.dna = src.connected.occupant.dna.Clone()
if(ishuman(connected.occupant))
- databuf.dna.real_name=connected.occupant.dna.real_name
+ var/mob/living/carbon/human/H = connected.occupant
+ databuf.dna.real_name = H.dna.real_name
+ databuf.gender = H.gender
+ databuf.body_descriptors = H.descriptors
databuf.name = "Unique Identifier + Unique Enzymes"
src.buffers[bufferId] = databuf
return 1
@@ -728,7 +736,10 @@
databuf.types = DNA2_BUF_SE
databuf.dna = src.connected.occupant.dna.Clone()
if(ishuman(connected.occupant))
- databuf.dna.real_name=connected.occupant.dna.real_name
+ var/mob/living/carbon/human/H = connected.occupant
+ databuf.dna.real_name = H.dna.real_name
+ databuf.gender = H.gender
+ databuf.body_descriptors = H.descriptors
databuf.name = "Structural Enzymes"
src.buffers[bufferId] = databuf
return 1
@@ -764,10 +775,18 @@
if ((buf.types & DNA2_BUF_UE))
src.connected.occupant.real_name = buf.dna.real_name
src.connected.occupant.name = buf.dna.real_name
+ if(ishuman(connected.occupant))
+ var/mob/living/carbon/human/H = connected.occupant
+ H.gender = buf.gender
+ H.descriptors = buf.body_descriptors
src.connected.occupant.UpdateAppearance(buf.dna.UI.Copy())
else if (buf.types & DNA2_BUF_SE)
src.connected.occupant.dna.SE = buf.dna.SE
src.connected.occupant.dna.UpdateSE()
+ if(ishuman(connected.occupant))
+ var/mob/living/carbon/human/H = connected.occupant
+ H.gender = buf.gender
+ H.descriptors = buf.body_descriptors
domutcheck(src.connected.occupant,src.connected)
src.connected.occupant.apply_effect(rand(20,50), IRRADIATE, check_protection = 0)
return 1
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 8e3cb117f9..52a31d5afe 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -113,6 +113,8 @@
if(!R.dna.real_name) //to prevent null names
R.dna.real_name = "clone ([rand(0,999)])"
H.real_name = R.dna.real_name
+ H.gender = R.gender
+ H.descriptors = R.body_descriptors
//Get the clone body ready
H.adjustCloneLoss(150) // New damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite
diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm
index 0baa68cf22..41c7a33a19 100644
--- a/code/game/machinery/frame.dm
+++ b/code/game/machinery/frame.dm
@@ -105,7 +105,6 @@
/datum/frame/frame_types/reagent_distillery
name = "Distillery"
frame_class = FRAME_CLASS_MACHINE
- circuit = /obj/item/weapon/circuitboard/distiller
frame_size = 4
/datum/frame/frame_types/display
@@ -192,13 +191,13 @@
//////////////////////////////
/obj/structure/frame
- anchored = 0
+ anchored = FALSE
name = "frame"
icon = 'icons/obj/stock_parts.dmi'
icon_state = "machine_0"
var/state = FRAME_PLACED
var/obj/item/weapon/circuitboard/circuit = null
- var/need_circuit = 1
+ var/need_circuit = TRUE
var/datum/frame/frame_types/frame_type = new /datum/frame/frame_types/machine
var/list/components = null
@@ -207,8 +206,8 @@
/obj/structure/frame/computer //used for maps
frame_type = new /datum/frame/frame_types/computer
- anchored = 1
- density = 1
+ anchored = TRUE
+ density = TRUE
/obj/structure/frame/examine(mob/user)
..()
@@ -260,14 +259,14 @@
pixel_y = (dir & 3)? (dir == NORTH ? -frame_type.y_offset : frame_type.y_offset) : 0
if(frame_type.circuit)
- need_circuit = 0
+ need_circuit = FALSE
circuit = new frame_type.circuit(src)
if(frame_type.name == "Computer")
- density = 1
+ density = TRUE
if(frame_type.frame_class == FRAME_CLASS_MACHINE)
- density = 1
+ density = TRUE
update_icon()
@@ -277,7 +276,7 @@
to_chat(user, "You start to wrench the frame into place.")
playsound(src.loc, P.usesound, 50, 1)
if(do_after(user, 20 * P.toolspeed))
- anchored = 1
+ anchored = TRUE
if(!need_circuit && circuit)
state = FRAME_FASTENED
check_components()
@@ -290,7 +289,7 @@
playsound(src, P.usesound, 50, 1)
if(do_after(user, 20 * P.toolspeed))
to_chat(user, "You unfasten the frame.")
- anchored = 0
+ anchored = FALSE
else if(istype(P, /obj/item/weapon/weldingtool))
if(state == FRAME_PLACED)
@@ -587,11 +586,11 @@
set src in oview(1)
if(usr.incapacitated())
- return 0
+ return FALSE
if(anchored)
to_chat(usr, "It is fastened to the floor therefore you can't rotate it!")
- return 0
+ return FALSE
src.set_dir(turn(src.dir, 90))
@@ -606,11 +605,11 @@
set src in oview(1)
if(usr.incapacitated())
- return 0
+ return FALSE
if(anchored)
to_chat(usr, "It is fastened to the floor therefore you can't rotate it!")
- return 0
+ return FALSE
src.set_dir(turn(src.dir, 270))
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 89182806db..d457ccf7d1 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -929,6 +929,12 @@
icon_state = "nymphplushie"
pokephrase = "Chirp!"
+/obj/item/toy/plushie/teshari
+ name = "teshari plush"
+ desc = "This is a plush teshari. Very soft, with a pompom on the tail. The toy is made well, as if alive. Looks like she is sleeping. Shhh!"
+ icon_state = "teshariplushie"
+ pokephrase = "Rya!"
+
/obj/item/toy/plushie/mouse
name = "mouse plush"
desc = "A plushie of a delightful mouse! What was once considered a vile rodent is now your very best friend."
@@ -1357,4 +1363,4 @@
icon_state = "tinyxmastree"
w_class = ITEMSIZE_TINY
force = 1
- throwforce = 1
\ No newline at end of file
+ throwforce = 1
diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm
index 937391737a..7d7d78eeba 100644
--- a/code/game/objects/items/weapons/material/shards.dm
+++ b/code/game/objects/items/weapons/material/shards.dm
@@ -63,55 +63,48 @@
/obj/item/weapon/material/shard/afterattack(var/atom/target, mob/living/carbon/human/user as mob)
var/active_hand //hand the shard is in
- var/will_break
- var/gloves_are_heavy = FALSE//this is a fucking mess
+ var/will_break = FALSE
+ var/protected_hands = FALSE //this is a fucking mess
var/break_damage = 4
var/light_glove_d = rand(2, 4)
var/no_glove_d = rand(4, 6)
- var/list/h_gloves = list(/obj/item/clothing/gloves/captain, /obj/item/clothing/gloves/cyborg,
- /obj/item/clothing/gloves/swat, /obj/item/clothing/gloves/combat,
- /obj/item/clothing/gloves/botanic_leather, /obj/item/clothing/gloves/duty,
- /obj/item/clothing/gloves/tactical, /obj/item/clothing/gloves/vox,
- /obj/item/clothing/gloves/gauntlets)
+ var/list/forbidden_gloves = list(
+ /obj/item/clothing/gloves/sterile,
+ /obj/item/clothing/gloves/knuckledusters
+ )
- if(istype(user.l_hand, src))
+ if(src == user.l_hand)
active_hand = BP_L_HAND
- else
+ else if(src == user.r_hand)
active_hand = BP_R_HAND
+ else
+ return // If it's not actually in our hands anymore, we were probably gentle with it
+
+ active_hand = (src == user.l_hand) ? BP_L_HAND : BP_R_HAND // May not actually be faster than an if-else block, but a little bit cleaner -Ater
if(prob(75))
will_break = TRUE
- else
- will_break = FALSE
- if(user.gloves && (user.gloves.body_parts_covered & HANDS))
- var/obj/item/clothing/gloves/UG = user.gloves.type
- for(var/I in h_gloves)
- if(UG == I)
- gloves_are_heavy = TRUE
- if(will_break)
- user.visible_message("[user] hit \the [target] with \the [src], shattering it!", "You shatter \the [src] in your hand!")
- playsound(user, pick('sound/effects/Glassbr1.ogg', 'sound/effects/Glassbr2.ogg', 'sound/effects/Glassbr3.ogg'), 30, 1)
- qdel(src)
+ if(user.gloves && (user.gloves.body_parts_covered & HANDS) && istype(user.gloves, /obj/item/clothing/gloves)) // Not-gloves aren't gloves, and therefore don't protect us
+ protected_hands = TRUE // If we're wearing gloves we can probably handle it just fine
+ for(var/I in forbidden_gloves)
+ if(istype(user.gloves, I)) // forbidden_gloves is a blacklist, so if we match anything in there, our hands are not protected
+ protected_hands = FALSE
+ break
- if(gloves_are_heavy == FALSE)
- to_chat(user, "\The [src] partially cuts into your hand through your gloves as you hit \the [target]!")
- if(will_break)
- user.visible_message("[user] hit \the [target] with \the [src], shattering it!", "You shatter \the [src] in your hand!")
- user.apply_damage(light_glove_d + break_damage, BRUTE, active_hand, 0 ,0, src, src.sharp, src.edge)
- playsound(user, pick('sound/effects/Glassbr1.ogg', 'sound/effects/Glassbr2.ogg', 'sound/effects/Glassbr3.ogg'), 30, 1)
- qdel(src)
- else
- user.apply_damage(light_glove_d, BRUTE, active_hand, 0 ,0, src, src.sharp, src.edge)
- else
+ if(user.gloves && !protected_hands)
+ to_chat(user, "\The [src] partially cuts into your hand through your gloves as you hit \the [target]!")
+ user.apply_damage(light_glove_d + will_break ? break_damage : 0, BRUTE, active_hand, 0, 0, src, src.sharp, src.edge) // Ternary to include break damage
+
+ else if(!user.gloves)
to_chat(user, "\The [src] cuts into your hand as you hit \the [target]!")
- if(will_break)
- user.visible_message("[user] hit \the [target] with \the [src], shattering it!", "You shatter \the [src] in your hand!")
- user.apply_damage(no_glove_d + break_damage, BRUTE, active_hand, 0 ,0, src, src.sharp, src.edge)
- playsound(user, pick('sound/effects/Glassbr1.ogg', 'sound/effects/Glassbr2.ogg', 'sound/effects/Glassbr3.ogg'), 30, 1)
- qdel(src)
- else
- user.apply_damage(no_glove_d, BRUTE, active_hand, 0 ,0, src, src.sharp, src.edge)
+ user.apply_damage(no_glove_d + will_break ? break_damage : 0, BRUTE, active_hand, 0, 0, src, src.sharp, src.edge)
+
+ if(will_break && src.loc == user) // If it's not in our hand anymore
+ user.visible_message("[user] hit \the [target] with \the [src], shattering it!", "You shatter \the [src] in your hand!")
+ playsound(user, pick('sound/effects/Glassbr1.ogg', 'sound/effects/Glassbr2.ogg', 'sound/effects/Glassbr3.ogg'), 30, 1)
+ qdel(src)
+ return
/obj/item/weapon/material/shard/Crossed(AM as mob|obj)
..()
diff --git a/code/modules/vore/appearance/sprite_accessories_vr.dm b/code/modules/vore/appearance/sprite_accessories_vr.dm
index 1298155cdd..efdb36d628 100644
--- a/code/modules/vore/appearance/sprite_accessories_vr.dm
+++ b/code/modules/vore/appearance/sprite_accessories_vr.dm
@@ -982,6 +982,16 @@
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
+/datum/sprite_accessory/tail/sneptail
+ name = "Snep/Furry Tail (vwag)"
+ desc = ""
+ icon_state = "sneptail"
+ ani_state = "sneptail_w"
+ do_colouration = 1
+ color_blend_mode = ICON_MULTIPLY
+ extra_overlay = "sneptail_mark"
+ extra_overlay_w = "sneptail_mark_w"
+
/datum/sprite_accessory/tail/tiger_new
name = "tiger tail (vwag)"
desc = ""
diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm
index 227e29f822..faf2d43d66 100644
--- a/code/modules/vore/eating/belly_obj_vr.dm
+++ b/code/modules/vore/eating/belly_obj_vr.dm
@@ -1,4 +1,5 @@
#define VORE_SOUND_FALLOFF 0.1
+#define VORE_SOUND_RANGE 3
//
// Belly system 2.0, now using objects instead of datums because EH at datums.
@@ -57,6 +58,7 @@
var/tmp/list/items_preserved = list() // Stuff that wont digest so we shouldn't process it again.
var/tmp/next_emote = 0 // When we're supposed to print our next emote, as a belly controller tick #
var/tmp/recent_sound = FALSE // Prevent audio spam
+ var/tmp/list/hearing_mobs
// Don't forget to watch your commas at the end of each line if you change these.
var/list/struggle_messages_outside = list(
@@ -248,7 +250,7 @@
//Place them into our drop_location
M.forceMove(drop_location())
-
+
items_preserved -= M
//Special treatment for absorbed prey
diff --git a/code/modules/vore/eating/bellymodes_vr.dm b/code/modules/vore/eating/bellymodes_vr.dm
index f66edcbf80..e879eeddd5 100644
--- a/code/modules/vore/eating/bellymodes_vr.dm
+++ b/code/modules/vore/eating/bellymodes_vr.dm
@@ -35,7 +35,7 @@
if(M.is_preference_enabled(/datum/client_preference/digestion_noises)) //then we check if the mob has sounds enabled at all
var/sound/preyloop = sound('sound/vore/sunesound/prey/loop.ogg')
M.playsound_local(get_turf(src),preyloop, 80,0, channel = CHANNEL_PREYLOOP)
- M.next_preyloop = (world.time + 52 SECONDS)
+ M.next_preyloop = (world.time + (52 SECONDS))
/////////////////////////// Sound Selections ///////////////////////////
var/sound/prey_digest
@@ -354,9 +354,18 @@
/////////////////////////// Make any noise ///////////////////////////
if(play_sound)
- for(var/mob/M in hearers(4, owner)) //so we don't fill the whole room with the sound effect
- if(M && M.client && (isturf(M.loc) || (M.loc != src.contents)) && M.is_preference_enabled(/datum/client_preference/digestion_noises)) //to avoid people on the inside getting the outside sounds and their direct sounds + built in sound pref check
- SEND_SOUND(M, play_sound) //these are all external sound triggers now, so it's ok.
+ LAZYCLEARLIST(hearing_mobs)
+ for(var/mob/M in hearers(VORE_SOUND_RANGE, owner))
+ if(!M.client || !(M.is_preference_enabled(/datum/client_preference/digestion_noises)))
+ continue
+ LAZYADD(hearing_mobs, M)
+ for(var/mob/M in hearing_mobs) //so we don't fill the whole room with the sound effect
+ if(M && M.client && (isturf(M.loc) || (M.loc != src.contents))) //to avoid people on the inside getting the outside sounds and their direct sounds + built in sound pref check
+ if(fancy_vore)
+ M.playsound_local(owner.loc, play_sound, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
+ else
+ M.playsound_local(owner.loc, play_sound, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF)
+ //these are all external sound triggers now, so it's ok.
if(to_update)
for(var/mob/living/M in contents)
if(M.client)
diff --git a/icons/mob/vore/tails_vr.dmi b/icons/mob/vore/tails_vr.dmi
index 134e4e9f31..8de015c01c 100644
Binary files a/icons/mob/vore/tails_vr.dmi and b/icons/mob/vore/tails_vr.dmi differ
diff --git a/icons/obj/stock_parts.dmi b/icons/obj/stock_parts.dmi
index 2bab59a487..2c6f880e66 100644
Binary files a/icons/obj/stock_parts.dmi and b/icons/obj/stock_parts.dmi differ
diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi
index 8cce2e7f15..f3e250f8e5 100644
Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ
diff --git a/maps/tether/submaps/admin_use/fun.dm b/maps/tether/submaps/admin_use/fun.dm
index 76c5be488b..090db293a4 100644
--- a/maps/tether/submaps/admin_use/fun.dm
+++ b/maps/tether/submaps/admin_use/fun.dm
@@ -32,7 +32,7 @@
requires_power = 0
dynamic_lighting = 0
-/area/submap/AU2
+/area/submap/admin_upload/AU2
name = "\improper Unknown Area A"
requires_power = 1
dynamic_lighting = 1
@@ -40,7 +40,7 @@
power_environ = FALSE
power_light = FALSE
-/area/submap/AU3
+/area/submap/admin_upload/AU3
name = "\improper Unknown Area B"
requires_power = 1
dynamic_lighting = 1
@@ -48,7 +48,7 @@
power_environ = FALSE
power_light = FALSE
-/area/submap/AU4
+/area/submap/admin_upload/AU4
name = "\improper Unknown Area C"
requires_power = 1
dynamic_lighting = 1
@@ -56,7 +56,7 @@
power_environ = FALSE
power_light = FALSE
-/area/submap/AU5
+/area/submap/admin_upload/AU5
name = "\improper Unknown Area D"
requires_power = 1
dynamic_lighting = 1
@@ -64,7 +64,7 @@
power_environ = FALSE
power_light = FALSE
-/area/submap/AU6
+/area/submap/admin_upload/AU6
name = "\improper Unknown Area E"
requires_power = 1
dynamic_lighting = 1