diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm
new file mode 100644
index 0000000000..cc6e5bd49a
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm
@@ -0,0 +1,3 @@
+/// Called from /mob/living/PushAM -- Called when this mob is about to push a movable, but before it moves
+/// (aotm/movable/being_pushed)
+#define COMSIG_LIVING_PUSHING_MOVABLE "living_pushing_movable"
diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
new file mode 100644
index 0000000000..5d2a471c0a
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm
@@ -0,0 +1,2 @@
+///From base of mob/living/MobBump() (mob/living)
+#define COMSIG_LIVING_MOB_BUMP "living_mob_bump"
diff --git a/code/__DEFINES/movement.dm b/code/__DEFINES/movement.dm
index 5bf7de8647..bccbd425dd 100644
--- a/code/__DEFINES/movement.dm
+++ b/code/__DEFINES/movement.dm
@@ -13,7 +13,7 @@ GLOBAL_VAR_INIT(glide_size_multiplier, 1.0)
/// Then that's multiplied by the global glide size multiplier. 1.25 by default feels pretty close to spot on. This is just to try to get byond to behave.
/// The whole result is then clamped to within the range above.
/// Not very readable but it works
-#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((32 / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE))
+#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((world.icon_size / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE))
/// Enables smooth movement
// #define SMOOTH_MOVEMENT
diff --git a/code/__HELPERS/matrices/transform_matrix.dm b/code/__HELPERS/matrices/transform_matrix.dm
index 251ef8151f..8f8a67535e 100644
--- a/code/__HELPERS/matrices/transform_matrix.dm
+++ b/code/__HELPERS/matrices/transform_matrix.dm
@@ -19,7 +19,7 @@
speed /= segments
if(parallel)
- animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL)
+ animate(src, transform = matrices[1], time = speed, loops, flags = ANIMATION_PARALLEL)
else
animate(src, transform = matrices[1], time = speed, loops)
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index 2771a3270b..0a9e68a790 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -379,6 +379,8 @@
parts += "[FOURSPACES]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]"
parts += "[FOURSPACES]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[popcount["station_integrity"]]%"]"
+ if(mode.station_was_nuked && SSevents.holidays && SSevents.holidays[PRIDE_MONTH])
+ parts += "[FOURSPACES]Gender revealed: [pick(500; "Male", 500; "Female", "Bigender", "Agender", "Demiboy", "Demigirl", "Genderfluid", "Pangender", "Xenogender", "Clown", 50; "What", 50; "Oh no.", 50; "Excuse me?")]"
var/total_players = GLOB.joined_player_list.len
if(total_players)
parts+= "[FOURSPACES]Total Population: [total_players]"
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index b415b4720f..428784e953 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1176,25 +1176,22 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
var/initialpixely = pixel_y
var/shiftx = rand(-pixelshiftx,pixelshiftx)
var/shifty = rand(-pixelshifty,pixelshifty)
- animate(src, pixel_x = pixel_x + shiftx, pixel_y = pixel_y + shifty, time = 0.2, loop = duration)
- pixel_x = initialpixelx
- pixel_y = initialpixely
+ animate(src, pixel_x = shiftx, pixel_y = shifty, time = 0.2, loop = duration, flags = ANIMATION_RELATIVE)
+ animate(pixel_x = initialpixelx, pixel_y = initialpixely, time = 0.2)
-/atom/proc/do_jiggle(targetangle = 45, timer = 20)
+/atom/proc/do_jiggle(targetangle = 25, timer = 20)
var/matrix/OM = matrix(transform)
var/matrix/M = matrix(transform)
- var/halftime = timer * 0.5
M.Turn(pick(-targetangle, targetangle))
- animate(src, transform = M, time = halftime, easing = ELASTIC_EASING)
- animate(src, transform = OM, time = halftime, easing = ELASTIC_EASING)
+ animate(src, transform = M, time = timer * 0.1, easing = BACK_EASING | EASE_IN)
+ animate(transform = OM, time = timer * 0.4, easing = ELASTIC_EASING)
/atom/proc/do_squish(squishx = 1.2, squishy = 0.6, timer = 20)
var/matrix/OM = matrix(transform)
var/matrix/M = matrix(transform)
- var/halftime = timer * 0.5
M.Scale(squishx, squishy)
- animate(src, transform = M, time = halftime, easing = BOUNCE_EASING)
- animate(src, transform = OM, time = halftime, easing = BOUNCE_EASING)
+ animate(src, transform = M, time = timer * 0.5, easing = ELASTIC_EASING)
+ animate(transform = OM, time = timer * 0.5, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
/proc/weightclass2text(var/w_class)
switch(w_class)
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 692f2317ef..d3d0fb32b6 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -60,7 +60,7 @@
if(client && hud_used)
hud_used.reorganize_alerts()
thealert.transform = matrix(32, 6, MATRIX_TRANSLATE)
- animate(thealert, transform = matrix(), time = 2.5, easing = CUBIC_EASING)
+ animate(thealert, transform = matrix(), time = 2.5, easing = BACK_EASING)
if(thealert.timeout)
addtimer(CALLBACK(src, .proc/alert_timeout, thealert, category), thealert.timeout)
diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm
index ce581685ed..8f237c4a71 100644
--- a/code/_onclick/hud/radial.dm
+++ b/code/_onclick/hud/radial.dm
@@ -178,7 +178,7 @@ GLOBAL_LIST_EMPTY(radial_menus)
starting.Scale(0.1,0.1)
E.transform = starting
var/matrix/TM = matrix()
- animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing)
+ animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing, easing = SINE_EASING | EASE_OUT)
else
E.pixel_y = py
E.pixel_x = px
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 8f3a7ef02c..23486cac29 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -126,6 +126,8 @@
return DISCARD_LAST_ACTION
user.do_attack_animation(O)
O.attacked_by(src, user)
+ if(force >= 20)
+ shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01))
/atom/movable/proc/attacked_by()
return
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index 1a5d54a306..79b3010b85 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -320,11 +320,11 @@ SUBSYSTEM_DEF(vote)
admintext += "\nIt should be noted that this is not a raw tally of votes but rather the median score plus a tiebreaker!"
for(var/i=1,i<=choices.len,i++)
var/votes = choices[choices[i]]
- admintext += "\n[choices[i]]: [votes]"
+ admintext += "\n[choices[i]]: [votes ? votes : "0"]" //This is raw data, but the raw data is null by default. If ya don't compensate for it, then it'll look weird!
else
for(var/i=1,i<=scores.len,i++)
var/score = scores[scores[i]]
- admintext += "\n[scores[i]]: [score]"
+ admintext += "\n[scores[i]]: [score ? score : "0"]"
message_admins(admintext)
return .
diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm
index 5eb89f4c10..f4a979c510 100644
--- a/code/datums/chatmessage.dm
+++ b/code/datums/chatmessage.dm
@@ -202,6 +202,7 @@
message.maptext_height = mheight
message.maptext_x = (CHAT_MESSAGE_WIDTH - owner.bound_width) * -0.5
message.maptext = MAPTEXT(complete_text)
+ message.pixel_x = -owner.pixel_x //Dogborgs and other wide boys have a pixel offset. This accounts for that
// View the message
LAZYADDASSOC(owned_by.seen_messages, message_loc, src)
@@ -212,10 +213,6 @@
scheduled_destruction = world.time + (lifespan - CHAT_MESSAGE_EOL_FADE)
enter_subsystem()
- var/mob/living/silicon/robot/R = target
- if(iscyborg(R))
- if((R.module.dogborg == TRUE || R.dogborg == TRUE) && isturf(R.loc)) //I hate whoever that thought that putting two types of dogborg that don't even sync up properly was good
- message.pixel_x = 16
/**
* Applies final animations to overlay CHAT_MESSAGE_EOL_FADE deciseconds prior to message deletion
diff --git a/code/datums/components/bouncy.dm b/code/datums/components/bouncy.dm
index fed603410e..3c4e228b59 100644
--- a/code/datums/components/bouncy.dm
+++ b/code/datums/components/bouncy.dm
@@ -32,7 +32,7 @@
var/atom/movable/A = parent
switch(rand(1, 3))
if(1)
- A.do_jiggle(45 + rand(-10, 10) * bouncy_mod, 14)
+ A.do_jiggle(25 + rand(-5, 5) * bouncy_mod, 14)
if(2)
var/min_b = 0.6/bouncy_mod
var/max_b = 1.2 * bouncy_mod
diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm
index 98bbdbed05..40daac88cf 100644
--- a/code/datums/components/storage/storage.dm
+++ b/code/datums/components/storage/storage.dm
@@ -432,25 +432,26 @@
if(M.incapacitated() || !M.canUseStorage())
return
var/atom/A = parent
- A.add_fingerprint(M)
// this must come before the screen objects only block, dunno why it wasn't before
if(over_object == M)
user_show_to_mob(M, trigger_on_found = TRUE)
if(isrevenant(M))
INVOKE_ASYNC(GLOBAL_PROC, .proc/RevenantThrow, over_object, M, source)
return
+ if(check_locked(null, M) || !M.CanReach(A) || (!M.CanReach(over_object) && !istype(over_object, /atom/movable/screen)))
+ return
+ playsound(A, "rustle", 50, TRUE, -5)
+ A.do_jiggle()
+ A.add_fingerprint(M)
if(!istype(over_object, /atom/movable/screen))
INVOKE_ASYNC(src, .proc/dump_content_at, over_object, M)
return
if(A.loc != M)
return
- playsound(A, "rustle", 50, TRUE, -5)
- A.do_jiggle()
if(istype(over_object, /atom/movable/screen/inventory/hand))
var/atom/movable/screen/inventory/hand/H = over_object
M.putItemFromInventoryInHandIfPossible(A, H.held_index)
return
- A.add_fingerprint(M)
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, trigger_on_found = FALSE)
var/atom/A = parent
diff --git a/code/datums/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm
index 56e06e3582..c0e6e9dba6 100644
--- a/code/datums/components/virtual_reality.dm
+++ b/code/datums/components/virtual_reality.dm
@@ -84,9 +84,9 @@
if(VR)
VR.level_below = src
level_above = VR
- M.transfer_ckey(vr_M, FALSE)
mastermind = M.mind
mastermind.current.audiovisual_redirect = parent
+ M.transfer_ckey(vr_M, FALSE)
RegisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER, .proc/switch_player)
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over)
RegisterSignal(M, COMSIG_MOB_PRE_PLAYER_CHANGE, .proc/player_hijacked)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 1de7a1576e..4077f86e52 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -1322,7 +1322,7 @@
filters += filter(arglist(arguments))
UNSETEMPTY(filter_data)
-/atom/proc/transition_filter(name, time, list/new_params, easing, loop)
+/atom/proc/transition_filter(name, time, list/new_params, easing, loop, parallel = TRUE)
var/filter = get_filter(name)
if(!filter)
return
@@ -1333,7 +1333,7 @@
for(var/thing in new_params)
params[thing] = new_params[thing]
- animate(filter, new_params, time = time, easing = easing, loop = loop)
+ animate(filter, new_params, time = time, easing = easing, loop = loop, flags = (parallel ? ANIMATION_PARALLEL : 0))
for(var/param in params)
filter_data[name][param] = params[param]
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 4b137d8b60..0323217341 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -605,11 +605,11 @@
if(throwing && !throw_override)
return
if(on && !(movement_type & FLOATING))
- animate(src, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
- animate(pixel_y = -2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
+ animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
+ animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
setMovetype(movement_type | FLOATING)
else if (!on && (movement_type & FLOATING))
- animate(src, pixel_y = initial(pixel_y), time = 10)
+ animate(src, pixel_z = initial(pixel_y), time = 10)
setMovetype(movement_type & ~FLOATING)
floating_need_update = FALSE // assume it's done
@@ -775,4 +775,4 @@
M.Turn(pick(-30, 30))
animate(I, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = M, easing = CUBIC_EASING)
sleep(1)
- animate(I, alpha = 0, transform = matrix(), time = 1)
+ animate(I, alpha = 0, transform = matrix(), time = 1, flags = ANIMATION_PARALLEL)
diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm
index 595b24d214..2b0b8da670 100644
--- a/code/game/objects/items/pneumaticCannon.dm
+++ b/code/game/objects/items/pneumaticCannon.dm
@@ -205,6 +205,10 @@
if(!throw_item(target, I, user))
break
+ if(user)
+ shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75))
+
+
/obj/item/pneumatic_cannon/proc/throw_item(turf/target, obj/item/I, mob/user)
if(!istype(I))
return FALSE
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index d48ddf880a..c1f20605a0 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -67,7 +67,7 @@
/obj/structure/proc/do_climb(atom/movable/A)
if(climbable)
density = FALSE
- . = step(A,get_dir(A,src.loc))
+ . = step(A, (A.loc == loc ? dir : get_dir(A,src.loc)))
density = TRUE
/obj/structure/proc/climb_structure(mob/living/user)
diff --git a/code/game/sound.dm b/code/game/sound.dm
index 38886e4908..02c2936f8d 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -110,7 +110,11 @@ distance_multiplier - Can be used to multiply the distance at which the sound is
*/
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance,
- falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0)
+ falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0, virtual_hearer)
+ if(audiovisual_redirect)
+ virtual_hearer = get_turf(src)
+ audiovisual_redirect.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, max_distance, falloff_distance, distance_multiplier, max(0, envwet), -10000, virtual_hearer)
+ //No return here, as we want to deliberately support the possibility of shenanigans in which mobs with clients can have active AV redirects to completely different players
if(!client)
return
@@ -134,7 +138,7 @@ distance_multiplier - Can be used to multiply the distance at which the sound is
S.frequency = get_rand_frequency()
if(isturf(turf_source))
- var/turf/T = get_turf(src)
+ var/turf/T = virtual_hearer || get_turf(src)
//sound volume falloff with distance
var/distance = get_dist(T, turf_source)
diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
index a6a30ba96e..1a3997272a 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
@@ -66,9 +66,21 @@
icon_state = "nuclearbomb_base"
anchored = TRUE //stops it being moved
+/obj/machinery/nuclearbomb/selfdestruct/Initialize(mapload)
+ . = ..()
+ if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH] && prob(10))
+ name = "station-wide gender-reveal terminal"
+ desc = "For when the whole sector deserves to know a gender. But of whom? Don't ask."
+
/obj/machinery/nuclearbomb/syndicate
//ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb
+/obj/machinery/nuclearbomb/syndicate/Initialize(mapload)
+ . = ..()
+ if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH] && prob(50))
+ name = "tactical gender-reveal device"
+ desc = "\"But whose gender is it revealing?\" you ponder. Don't worry. That comes later."
+
/obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station)
var/datum/game_mode/nuclear/NM = SSticker.mode
switch(off_station)
diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm
index 6fc0fabf31..d3ad2ca4c7 100644
--- a/code/modules/clothing/gloves/miscellaneous.dm
+++ b/code/modules/clothing/gloves/miscellaneous.dm
@@ -360,3 +360,12 @@
desc = "Thin, pretty gloves intended for use in sexy feminine attire. A tag on the hem claims they pair great with black stockings."
icon_state = "eveningblack"
item_state = "eveningblack"
+
+/obj/item/clothing/gloves/polymaid
+ name = "polychromic maid gloves"
+ desc = "Colourable maid gloves!"
+ icon_state = "maid_arms"
+
+/obj/item/clothing/gloves/polymaid/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2)
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index 4e7ccb7111..f3868f703f 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -477,6 +477,15 @@
item_state = "maid"
dynamic_hair_suffix = ""
+/obj/item/clothing/head/maid/polychromic
+ name = "polychromic maid headband"
+ icon_state = "polymaid"
+ item_state = "polymaid"
+
+/obj/item/clothing/head/maid/polychromic/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2)
+
/obj/item/clothing/head/widered
name = "Wide red hat"
desc = "It is both wide, and red. Stylish!"
diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm
index 7f4de22bb4..7ac2f65205 100644
--- a/code/modules/clothing/neck/_neck.dm
+++ b/code/modules/clothing/neck/_neck.dm
@@ -259,6 +259,15 @@
name = "Collar Key"
desc = "A key for a tiny lock on a collar or bag."
+/obj/item/clothing/neck/maid
+ name = "polychromic maid collar"
+ desc = "A collar that goes with the polychromic maid outfit."
+ icon_state = "maid_neck"
+
+/obj/item/clothing/neck/maid/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2)
+
//////////////
//DOPE BLING//
//////////////
diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm
index 41bdb3d5ca..6806f73c65 100644
--- a/code/modules/clothing/suits/_suits.dm
+++ b/code/modules/clothing/suits/_suits.dm
@@ -26,15 +26,12 @@
var/mob/living/carbon/human/M = loc
if(ishuman(M) && M.w_uniform)
var/obj/item/clothing/under/U = M.w_uniform
- //SKYRAT EDIT
+ //SANDSTORM EDIT
if(istype(U) && length(U.attached_accessories))
- var/please_overlay = FALSE
for(var/obj/item/clothing/accessory/attached in U.attached_accessories)
if(attached.above_suit)
- please_overlay = TRUE
- if(please_overlay)
- . += U.accessory_overlay
- //SKYRAT EDIT END
+ . += U.accessory_overlays
+ //SANDSTORM EDIT END
/obj/item/clothing/suit/update_clothes_damaged_state()
..()
diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm
index d9a090a9a7..c87095e5ff 100644
--- a/code/modules/clothing/under/_under.dm
+++ b/code/modules/clothing/under/_under.dm
@@ -22,11 +22,11 @@
var/adjusted = NORMAL_STYLE
var/alt_covers_chest = FALSE // for adjusted/rolled-down jumpsuits, FALSE = exposes chest and arms, TRUE = exposes arms only
var/dummy_thick = FALSE // is able to hold accessories on its item
- //SKYRAT EDIT - Removed the old attached accessory system. We use a list of accessories instead.
- var/list/obj/item/clothing/accessory/attached_accessories = list()
+ //SANDSTORM EDIT - Removed the old attached accessory system. We use a list of accessories instead.
var/max_accessories = 3
- //SKYRAT EDIT END
- var/mutable_appearance/accessory_overlay
+ var/list/obj/item/clothing/accessory/attached_accessories = list()
+ var/list/mutable_appearance/accessory_overlays = list()
+ //SANDSTORM EDIT END
/obj/item/clothing/under/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
@@ -36,8 +36,8 @@
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
if(blood_DNA)
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend())
- if(accessory_overlay)
- . += accessory_overlay
+ if(length(accessory_overlays))
+ . += accessory_overlays
/obj/item/clothing/under/attackby(obj/item/I, mob/user, params)
if((sensordamage || (has_sensor < HAS_SENSORS && has_sensor != NO_SENSORS)) && istype(I, /obj/item/stack/cable_coil))
@@ -164,14 +164,18 @@
if((flags_inv & HIDEACCESSORY) || (A.flags_inv & HIDEACCESSORY))
return TRUE
- //SKYRAT EDIT
- accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', "blank")
+ //SANDSTORM EDIT
+ accessory_overlays = list(mutable_appearance('icons/mob/clothing/accessories.dmi', "blank"))
for(var/obj/item/clothing/accessory/attached_accessory in attached_accessories)
- var/mutable_appearance/Y = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.icon_state, ABOVE_HUD_LAYER)
- Y.alpha = attached_accessory.alpha
- Y.color = attached_accessory.color
- accessory_overlay.add_overlay(Y)
- //SKYRAT EDIT END
+ var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays")
+ if(!polychromic)
+ var/mutable_appearance/accessory_overlay = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, ABOVE_HUD_LAYER)
+ accessory_overlay.alpha = attached_accessory.alpha
+ accessory_overlay.color = attached_accessory.color
+ accessory_overlays += accessory_overlay
+ else
+ polychromic.apply_worn_overlays(attached_accessory, FALSE, attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, NONE, accessory_overlays)
+ //SANDSTORM EDIT END
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm
index 63d09a89de..e39c48f80f 100644
--- a/code/modules/clothing/under/accessories.dm
+++ b/code/modules/clothing/under/accessories.dm
@@ -48,9 +48,9 @@
TakeComponent(detached_pockets)
U.armor = U.armor.detachArmor(armor)
- //SKYRAT EDIT
+ //SANDSTORM EDIT
current_uniform = null
- //SKYRAT EDIT END
+ //SANDSTORM EDIT END
if(isliving(user))
on_uniform_dropped(U, user)
@@ -61,18 +61,23 @@
pixel_y = 0
layer = initial(layer)
plane = initial(plane)
- U.accessory_overlay = null
U.cut_overlays()
U.attached_accessories -= src
+ U.accessory_overlays = list()
if(length(U.attached_accessories))
- U.accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', "blank", WRISTS_LAYER, U.plane)
+ U.accessory_overlays = list(mutable_appearance('icons/mob/clothing/accessories.dmi', "blank"))
for(var/obj/item/clothing/accessory/attached_accessory in U.attached_accessories)
attached_accessory.force_unto(U)
- var/mutable_appearance/Y = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.icon_state, WRISTS_LAYER, U.plane)
- Y.alpha = attached_accessory.alpha
- Y.color = attached_accessory.color
- U.accessory_overlay.add_overlay(Y)
-//SKYRAT EDIT
+ var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays")
+ if(!polychromic)
+ var/mutable_appearance/accessory_overlay = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, ABOVE_HUD_LAYER)
+ accessory_overlay.alpha = attached_accessory.alpha
+ accessory_overlay.color = attached_accessory.color
+ U.accessory_overlays += accessory_overlay
+ else
+ polychromic.apply_worn_overlays(attached_accessory, FALSE, attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, NONE, U.accessory_overlays)
+
+//SANDSTORM EDIT
/obj/item/clothing/accessory/proc/force_unto(obj/item/clothing/under/U)
layer = FLOAT_LAYER
plane = FLOAT_PLANE
@@ -98,7 +103,7 @@
pixel_x += rand(-16, 16)
pixel_y += rand(-16, 16)
U.add_overlay(src)
-//SKYRAT EDIT END
+//SANDSTORM EDIT END
/obj/item/clothing/accessory/proc/on_uniform_equip(obj/item/clothing/under/U, user)
return
@@ -296,6 +301,15 @@
item_state = "maidapron"
minimize_when_attached = FALSE
+/obj/item/clothing/accessory/maidapron/polychromic
+ name = "polychromic maid apron"
+ icon_state = "polymaidapron"
+ item_state = "polymaidapron"
+
+/obj/item/clothing/accessory/maidapron/polychromic/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2)
+
/obj/item/clothing/accessory/sleevecrop
name = "one sleeved crop top"
desc = "Off the shoulder crop top, for those nights out partying."
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 53a4b0e997..2dcb8ef98f 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -121,7 +121,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
remove_verb(src, /mob/dead/observer/verb/boo)
remove_verb(src, /mob/dead/observer/verb/possess)
- animate(src, pixel_y = 2, time = 10, loop = -1)
+ animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
+ animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
add_to_dead_mob_list()
@@ -539,8 +540,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/stop_orbit(datum/component/orbiter/orbits)
. = ..()
//restart our floating animation after orbit is done.
- pixel_y = 0
- animate(src, pixel_y = 2, time = 10, loop = -1)
+ pixel_z = 0
+ animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
+ animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
set category = "Ghost"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
index 9563959ebc..ff4a7d2bba 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
@@ -51,7 +51,7 @@
// update_icons() //Handled in update_transform(), leaving this here as a reminder
update_transform()
-/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that.
+/mob/living/carbon/alien/humanoid/update_transform(do_animate) //The old method of updating lying/standing was update_icons(). Aliens still expect that.
if(lying > 0)
lying = 90 //Anything else looks silly
..()
diff --git a/code/modules/mob/living/carbon/alien/larva/update_icons.dm b/code/modules/mob/living/carbon/alien/larva/update_icons.dm
index e6e7e657e8..85416261c7 100644
--- a/code/modules/mob/living/carbon/alien/larva/update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/larva/update_icons.dm
@@ -21,7 +21,7 @@
else
icon_state = "larva[state]"
-/mob/living/carbon/alien/larva/update_transform() //All this is handled in update_icons()
+/mob/living/carbon/alien/larva/update_transform(do_animate) //All this is handled in update_icons()
..()
return update_icons()
diff --git a/code/modules/mob/living/carbon/monkey/punpun.dm b/code/modules/mob/living/carbon/monkey/punpun.dm
index c8b8dbbc9d..8fd7b45b65 100644
--- a/code/modules/mob/living/carbon/monkey/punpun.dm
+++ b/code/modules/mob/living/carbon/monkey/punpun.dm
@@ -46,6 +46,7 @@
..()
/mob/living/carbon/monkey/punpun/proc/Read_Memory()
+ var/saved_color
if(fexists("data/npc_saves/Punpun.sav")) //legacy compatability to convert old format to new
var/savefile/S = new /savefile("data/npc_saves/Punpun.sav")
S["ancestor_name"] >> ancestor_name
@@ -62,6 +63,9 @@
ancestor_chain = json["ancestor_chain"]
relic_hat = json["relic_hat"]
relic_mask = json["relic_hat"]
+ saved_color = json["color"]
+ if(!isnull(saved_color))
+ add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY)
/mob/living/carbon/monkey/punpun/proc/Write_Memory(dead, gibbed)
var/json_file = file("data/npc_saves/Punpun.json")
@@ -71,10 +75,12 @@
file_data["ancestor_chain"] = null
file_data["relic_hat"] = null
file_data["relic_mask"] = null
+ file_data["color"] = null
else
file_data["ancestor_name"] = ancestor_name ? ancestor_name : name
file_data["ancestor_chain"] = dead ? ancestor_chain + 1 : ancestor_chain
file_data["relic_hat"] = head ? head.type : null
file_data["relic_mask"] = wear_mask ? wear_mask.type : null
+ file_data["color"] = color ? json_encode(color) : null
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 6efa32b48b..e9150f202d 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -81,6 +81,7 @@
//Called when we bump onto a mob
/mob/living/proc/MobBump(mob/M)
+ SEND_SIGNAL(src, COMSIG_LIVING_MOB_BUMP, M)
//Even if we don't push/swap places, we "touched" them, so spread fire
spreadFire(M)
@@ -88,6 +89,7 @@
return TRUE
var/they_can_move = TRUE
+
if(isliving(M))
var/mob/living/L = M
they_can_move = CHECK_MOBILITY(L, MOBILITY_MOVE)
@@ -105,16 +107,16 @@
//Should stop you pushing a restrained person out of the way
if(L.pulledby && L.pulledby != src && L.restrained())
if(!(world.time % 5))
- to_chat(src, "[L] is restrained, you cannot push past.")
- return 1
+ to_chat(src, span_warning("[L] is restrained, you cannot push past."))
+ return TRUE
if(L.pulling)
if(ismob(L.pulling))
var/mob/P = L.pulling
if(P.restrained())
if(!(world.time % 5))
- to_chat(src, "[L] is restraining [P], you cannot push past.")
- return 1
+ to_chat(src, span_warning("[L] is restraining [P], you cannot push past."))
+ return TRUE
//CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks or over prone bodies without a short delay
if(!CHECK_MOBILITY(src, MOBILITY_STAND))
@@ -142,7 +144,7 @@
//END OF CIT CHANGES
if(moving_diagonally)//no mob swap during diagonal moves.
- return 1
+ return TRUE
//handle micro bumping on help intent
if(a_intent == INTENT_HELP)
@@ -156,7 +158,8 @@
if(!too_strong)
mob_swap = TRUE
else
- if(M.pulledby == src && a_intent == INTENT_GRAB)
+ //You can swap with the person you are dragging on grab intent, and restrained people in most cases
+ if(M.pulledby == src && !too_strong)
mob_swap = TRUE
//restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller
else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP))
@@ -164,8 +167,8 @@
if(mob_swap)
//switch our position with M
if(loc && !loc.Adjacent(M.loc))
- return 1
- now_pushing = 1
+ return TRUE
+ now_pushing = TRUE
var/oldloc = loc
var/oldMloc = M.loc
@@ -185,29 +188,33 @@
if(!M_passmob)
M.pass_flags &= ~PASSMOB
- now_pushing = 0
+ now_pushing = FALSE
if(!move_failed)
- return 1
+ return TRUE
//okay, so we didn't switch. but should we push?
//not if he's not CANPUSH of course
if(!(M.status_flags & CANPUSH))
- return 1
+ return TRUE
if(handle_micro_bump_other(M))
return TRUE
if(isliving(M))
var/mob/living/L = M
if(HAS_TRAIT(L, TRAIT_PUSHIMMUNE))
- return 1
- //If they're a human, and they're not in help intent, block pushing
- if(ishuman(M) && (M.a_intent != INTENT_HELP))
- return TRUE
+ return TRUE
+ if(M.a_intent != INTENT_HELP)
+ //If they're a human, and they're not in help intent, block pushing
+ if(ishuman(M))
+ return TRUE
+ //if they are a cyborg, and they're alive and not in help intent, block pushing
+ if(iscyborg(M) && M.stat != DEAD)
+ return TRUE
//anti-riot equipment is also anti-push
for(var/obj/item/I in M.held_items)
if(!istype(M, /obj/item/clothing))
if(prob(I.block_chance*2))
- return 1
+ return TRUE
/mob/living/get_photo_description(obj/item/camera/camera)
var/list/mob_details = list()
@@ -238,21 +245,40 @@
if(!client && (mob_size < MOB_SIZE_SMALL))
return
now_pushing = TRUE
- var/t = get_dir(src, AM)
+ SEND_SIGNAL(src, COMSIG_LIVING_PUSHING_MOVABLE, AM)
+ var/dir_to_target = get_dir(src, AM)
+
+ // If there's no dir_to_target then the player is on the same turf as the atom they're trying to push.
+ // This can happen when a player is stood on the same turf as a directional window. All attempts to push
+ // the window will fail as get_dir will return 0 and the player will be unable to move the window when
+ // it should be pushable.
+ // In this scenario, we will use the facing direction of the /mob/living attempting to push the atom as
+ // a fallback.
+ if(!dir_to_target)
+ dir_to_target = dir
+
var/push_anchored = FALSE
if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force)
- if(move_crush(AM, move_force, t))
+ if(move_crush(AM, move_force, dir_to_target))
push_anchored = TRUE
- if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally
- if(force_push(AM, move_force, t, push_anchored))
+ if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally
+ if(force_push(AM, move_force, dir_to_target, push_anchored))
push_anchored = TRUE
+ if(ismob(AM))
+ var/mob/mob_to_push = AM
+ var/atom/movable/mob_buckle = mob_to_push.buckled
+ // If we can't pull them because of what they're buckled to, make sure we can push the thing they're buckled to instead.
+ // If neither are true, we're not pushing anymore.
+ if(mob_buckle && (mob_buckle.buckle_prevents_pull || (force < (mob_buckle.move_resist * MOVE_FORCE_PUSH_RATIO))))
+ now_pushing = FALSE
+ return
if((AM.anchored && !push_anchored) || (force < (AM.move_resist * MOVE_FORCE_PUSH_RATIO)))
now_pushing = FALSE
return
- if (istype(AM, /obj/structure/window))
+ if(istype(AM, /obj/structure/window))
var/obj/structure/window/W = AM
if(W.fulltile)
- for(var/obj/structure/window/win in get_step(W,t))
+ for(var/obj/structure/window/win in get_step(W, dir_to_target))
now_pushing = FALSE
return
if(pulling == AM)
@@ -260,8 +286,9 @@
var/current_dir
if(isliving(AM))
current_dir = AM.dir
- if(step(AM, t) && Process_Spacemove(t))
- step(src, t)
+ if(AM.Move(get_step(AM.loc, dir_to_target), dir_to_target, glide_size))
+ AM.add_fingerprint(src)
+ Move(get_step(loc, dir_to_target), dir_to_target)
if(current_dir)
AM.setDir(current_dir)
now_pushing = FALSE
@@ -361,29 +388,33 @@
offset = GRAB_PIXEL_SHIFT_NECK
if(GRAB_KILL)
offset = GRAB_PIXEL_SHIFT_NECK
- M.setDir(get_dir(M, src))
- switch(M.dir)
- if(NORTH)
- animate(M, pixel_x = 0, pixel_y = offset, 3)
- if(SOUTH)
- animate(M, pixel_x = 0, pixel_y = -offset, 3)
- if(EAST)
- if(M.lying == 270) //update the dragged dude's direction if we've turned
- M.lying = 90
- M.update_transform() //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so
- M.lying_prev = M.lying
- animate(M, pixel_x = offset, pixel_y = 0, 3)
- if(WEST)
- if(M.lying == 90)
- M.lying = 270
- M.update_transform()
- M.lying_prev = M.lying
- animate(M, pixel_x = -offset, pixel_y = 0, 3)
+ var/target_dir = get_dir(M, src)
+ M.setDir(target_dir)
+ var/target_x
+ var/target_y
+ if(target_dir & NORTH)
+ target_y += offset
+ if(target_dir & SOUTH)
+ target_y -= offset
+ if(target_dir & EAST)
+ target_x += offset
+ if(target_dir & WEST)
+ target_x -= offset
+ if(target_x || target_y)
+ if(0 < target_x && M.lying == 270)
+ M.lying = 90
+ M.update_transform(FALSE) //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so
+ M.lying_prev = M.lying
+ if(0 > target_x && M.lying == 90)
+ M.lying = 270
+ M.update_transform(FALSE)
+ M.lying_prev = M.lying
+ animate(M, pixel_x = target_x, pixel_y = target_y, time = 3, flags = ANIMATION_PARALLEL)
/mob/living/proc/reset_pull_offsets(mob/living/M, override)
if(!override && M.buckled)
return
- animate(M, pixel_x = 0, pixel_y = 0, 1)
+ animate(M, pixel_x = 0, pixel_y = 0, time = 3, flags = ANIMATION_PARALLEL)
//mob verbs are a lot faster than object verbs
//for more info on why this is not atom/pull, see examinate() in mob.dm
@@ -901,12 +932,11 @@
if(anchored || (buckled && buckled.anchored))
fixed = 1
if(on && !(movement_type & FLOATING) && !fixed)
- animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
- sleep(10)
- animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
+ animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
+ animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
setMovetype(movement_type | FLOATING)
else if(((!on || fixed) && (movement_type & FLOATING)))
- animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10)
+ animate(src, pixel_z = get_standard_pixel_y_offset(lying), time = 10)
setMovetype(movement_type & ~FLOATING)
// The src mob is trying to strip an item from someone
@@ -1005,7 +1035,7 @@
var/pixel_y_diff = rand(-amplitude/3, amplitude/3)
var/final_pixel_x = get_standard_pixel_x_offset(lying)
var/final_pixel_y = get_standard_pixel_y_offset(lying)
- animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6)
+ animate(src, pixel_x = pixel_x_diff, pixel_y = pixel_y_diff , time = 2, loop = 6, flags = ANIMATION_PARALLEL | ANIMATION_RELATIVE)
animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2)
floating_need_update = TRUE
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 49a60c0411..f9fcb35377 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -249,7 +249,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
/mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) //parent calls can't overwrite the current proc args.
- if(!client)
+ if(!client && !audiovisual_redirect)
return
var/deaf_message
var/deaf_type
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index 0d04d4b562..c1897c3c05 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -136,6 +136,7 @@
..()
/mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory()
+ var/saved_color
if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
S["family"] >> family
@@ -146,14 +147,21 @@
return
var/list/json = json_decode(file2text(json_file))
family = json["family"]
+ saved_color = json["color"]
if(isnull(family))
family = list()
+ if(!isnull(saved_color))
+ add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY)
/mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead)
var/json_file = file("data/npc_saves/Runtime.json")
var/list/file_data = list()
family = list()
if(!dead)
+ if(color)
+ file_data["color"] = json_encode(color)
+ else
+ file_data["color"] = null
for(var/mob/living/simple_animal/pet/cat/kitten/C in children)
if(istype(C,type) || C.stat || !C.z || !C.butcher_results) //That last one is a work around for hologram cats
continue
@@ -161,6 +169,8 @@
family[C.type] += 1
else
family[C.type] = 1
+ else
+ file_data["color"] = null
file_data["family"] = family
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index bce46fe10d..748a182ba3 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -436,6 +436,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Read_Memory()
set waitfor = FALSE
+ var/saved_color
if(fexists("data/npc_saves/Ian.sav")) //legacy compatability to convert old format to new
var/savefile/S = new /savefile("data/npc_saves/Ian.sav")
S["age"] >> age
@@ -450,12 +451,15 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
age = json["age"]
record_age = json["record_age"]
saved_head = json["saved_head"]
+ saved_color = json["color"]
if(isnull(age))
age = 0
if(isnull(record_age))
record_age = 1
if(saved_head)
place_on_head(new saved_head)
+ if(!isnull(saved_color))
+ add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY)
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Write_Memory(dead)
var/json_file = file("data/npc_saves/Ian.json")
@@ -470,10 +474,15 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
file_data["saved_head"] = inventory_head.type
else
file_data["saved_head"] = null
+ if(color)
+ file_data["color"] = json_encode(color)
+ else
+ file_data["color"] = null
else
file_data["age"] = 0
file_data["record_age"] = record_age
file_data["saved_head"] = null
+ file_data["color"] = null
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 1f12195ad6..c05aba8227 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -910,11 +910,13 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
speak += pick("...[longest_survival].", "The things I've seen!", "I have lived many lives!", "What are you before me?")
desc += " Old as sin, and just as loud. Claimed to be [rounds_survived]."
speak_chance = 20 //His hubris has made him more annoying/easier to justify killing
- add_atom_colour("#EEEE22", FIXED_COLOUR_PRIORITY)
+ if(!color)
+ add_atom_colour("#EEEE22", FIXED_COLOUR_PRIORITY)
else if(rounds_survived == longest_deathstreak)
speak += pick("What are you waiting for!", "Violence breeds violence!", "Blood! Blood!", "Strike me down if you dare!")
desc += " The squawks of [-rounds_survived] dead parrots ring out in your ears..."
- add_atom_colour("#BB7777", FIXED_COLOUR_PRIORITY)
+ if(!color)
+ add_atom_colour("#BB7777", FIXED_COLOUR_PRIORITY)
else if(rounds_survived > 0)
speak += pick("...again?", "No, It was over!", "Let me out!", "It never ends!")
desc += " Over [rounds_survived] shifts without a \"terrible\" \"accident\"!"
@@ -947,6 +949,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
..(gibbed)
/mob/living/simple_animal/parrot/Poly/proc/Read_Memory()
+ var/saved_color
if(fexists("data/npc_saves/Poly.sav")) //legacy compatability to convert old format to new
var/savefile/S = new /savefile("data/npc_saves/Poly.sav")
S["phrases"] >> speech_buffer
@@ -963,8 +966,11 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
rounds_survived = json["roundssurvived"]
longest_survival = json["longestsurvival"]
longest_deathstreak = json["longestdeathstreak"]
+ saved_color = json["color"]
if(!islist(speech_buffer))
speech_buffer = list()
+ if(!isnull(saved_color))
+ add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY)
/mob/living/simple_animal/parrot/Poly/proc/Write_Memory(dead)
var/json_file = file("data/npc_saves/Poly.json")
@@ -978,6 +984,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
file_data["longestdeathstreak"] = rounds_survived - 1
else
file_data["longestdeathstreak"] = longest_deathstreak
+ file_data["color"] = null
else
file_data["roundssurvived"] = rounds_survived + 1
if(rounds_survived + 1 > longest_survival)
@@ -985,6 +992,10 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
else
file_data["longestsurvival"] = longest_survival
file_data["longestdeathstreak"] = longest_deathstreak
+ if(color)
+ file_data["color"] = json_encode(color)
+ else
+ file_data["color"] = null
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 5b487f503e..1671c4bca9 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -482,7 +482,7 @@
update_action_buttons_icon()
return mobility_flags
-/mob/living/simple_animal/update_transform()
+/mob/living/simple_animal/update_transform(do_animate)
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/changed = 0
diff --git a/code/modules/mob/living/update_icons.dm b/code/modules/mob/living/update_icons.dm
index d3264c93a2..4ad861bf2b 100644
--- a/code/modules/mob/living/update_icons.dm
+++ b/code/modules/mob/living/update_icons.dm
@@ -1,5 +1,5 @@
//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
-/mob/living/update_transform()
+/mob/living/update_transform(do_animate = TRUE)
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/final_pixel_y = pixel_y
var/changed = 0
@@ -25,5 +25,9 @@
resize = RESIZE_DEFAULT_SIZE
if(changed)
- animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT)
+ if(do_animate)
+ animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT, flags = ANIMATION_PARALLEL)
+ else
+ transform = ntransform
+ pixel_y = final_pixel_y
floating_need_update = TRUE
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index f22c87913f..cfc2a6822a 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -141,7 +141,7 @@
return
hearers -= ignored_mobs
- if(target_message && target && istype(target) && target.client)
+ if(target_message && target && istype(target) && (target.client || target.audiovisual_redirect))
hearers -= target
if(omni)
target.show_message(target_message)
@@ -158,7 +158,7 @@
if(self_message)
hearers -= src
for(var/mob/M in hearers)
- if(!M.client)
+ if(!M.client && !M.audiovisual_redirect)
continue
if(omni)
M.show_message(message)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index a3bcdb0e55..f59ed15c88 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -229,17 +229,23 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
return copytext_char(sanitize(.),1,MAX_MESSAGE_LEN)
/proc/shake_camera(mob/M, duration, strength=1)
- if(!M || !M.client || duration < 1)
+ set waitfor = FALSE
+ if(!M || !M.client || duration <= 0)
return
var/client/C = M.client
+ if (C.prefs.screenshake==0)
+ return
var/oldx = C.pixel_x
var/oldy = C.pixel_y
- var/max = strength*world.icon_size
- var/min = -(strength*world.icon_size)
+ var/clientscreenshake = (C.prefs.screenshake * 0.01)
+ var/max = (strength*clientscreenshake) * world.icon_size
+ var/min = -((strength*clientscreenshake) * world.icon_size)
+ var/roundedduration = -round(-duration) // round() with only one arg will always round down. so uh. this is Something all right
- for(var/i in 0 to duration-1)
+ for(var/i in 0 to roundedduration-1)
+ duration--
if (i == 0)
- animate(C, pixel_x=rand(min,max), pixel_y=rand(min,max), time=1)
+ animate(C, pixel_x=(rand(min,max)*duration), pixel_y=(rand(min,max)*duration), time=1)
else
animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1)
animate(pixel_x=oldx, pixel_y=oldy, time=1)
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index 836ed3b804..3f2f4d3e65 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -3,6 +3,7 @@
name = "projectile gun"
icon_state = "pistol"
w_class = WEIGHT_CLASS_NORMAL
+ recoil = 0.25
var/spawnwithmagazine = TRUE
var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info
var/obj/item/ammo_box/magazine/magazine
diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm
index afb30631e0..fe42fc2d99 100644
--- a/code/modules/projectiles/guns/ballistic/revolver.dm
+++ b/code/modules/projectiles/guns/ballistic/revolver.dm
@@ -5,6 +5,7 @@
mag_type = /obj/item/ammo_box/magazine/internal/cylinder
fire_sound = "sound/weapons/revolvershot.ogg"
casing_ejector = FALSE
+ recoil = 0.5
/obj/item/gun/ballistic/revolver/Initialize(mapload)
. = ..()
@@ -285,6 +286,7 @@
item_state = "shotgun"
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_MEDIUM
+ recoil = 1
force = 10
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm
index c6fd27b103..25e4b6b12a 100644
--- a/code/modules/projectiles/guns/ballistic/shotgun.dm
+++ b/code/modules/projectiles/guns/ballistic/shotgun.dm
@@ -5,6 +5,7 @@
item_state = "shotgun"
fire_sound = "sound/weapons/gunshotshotgunshot.ogg"
w_class = WEIGHT_CLASS_BULKY
+ recoil = 1
force = 10
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index dd759f9e3c..03dfc46713 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -16,6 +16,7 @@
name = "energy gun"
desc = "A basic energy-based gun."
icon = 'icons/obj/guns/energy.dmi'
+ recoil = 0.1
var/obj/item/stock_parts/cell/cell //What type of power cell this uses
var/cell_type = /obj/item/stock_parts/cell
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index 3f41ac859f..9b10a843e8 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -8,6 +8,7 @@
item_flags = NONE
obj_flags = UNIQUE_RENAME
weapon_weight = WEAPON_LIGHT
+ recoil = 0.5
can_flashlight = 1
flight_x_offset = 15
flight_y_offset = 9
diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm
index 07066023b3..8de7633a79 100644
--- a/code/modules/projectiles/guns/misc/syringe_gun.dm
+++ b/code/modules/projectiles/guns/misc/syringe_gun.dm
@@ -4,6 +4,7 @@
icon_state = "syringegun"
item_state = "syringegun"
w_class = WEIGHT_CLASS_NORMAL
+ recoil = 0.1
throw_speed = 3
throw_range = 7
force = 4
diff --git a/html/changelogs/archive/2022-06.yml b/html/changelogs/archive/2022-06.yml
index acc02cf68c..2076f908ef 100644
--- a/html/changelogs/archive/2022-06.yml
+++ b/html/changelogs/archive/2022-06.yml
@@ -120,6 +120,7 @@
BongaTheProto:
- tweak: Makes the new player panel a toggle so you can choose between the old one
and TG's current. Option in Game Preferences
+2022-06-06:
SandPoot:
- refactor: Completely replaces the new player panel *not the admin one* with TG's.
timothyteakettle:
@@ -149,3 +150,42 @@
- code_imp: changes some things to use the cooldown system
- code_imp: puts signal handlers in a couple procs where they needed to be
- code_imp: Adds a signal for when mobs use emotes
+ Bhijn & Myr:
+ - rscadd: During pride month, station nukes are significantly more efficient at
+ revealing genders.
+ - rscadd: Station pets now retain their color between shifts!
+ - bugfix: Admin vote deobfuscation now properly displays votes as 0 if they were
+ simply never voted for.
+ - bugfix: Audiovisual redirection now works exactly as it used to. In laymen's terms,
+ this means folks in VR sleepers are aware of the world around them again!
+ - bugfix: The shake animation, jiggle animation, squish animation, jitter animation,
+ and float animation, have all been fixed.
+ - bugfix: This also means that storage animations are fully working again. It's
+ been a few years!
+ - bugfix: The pull animation no longer interrupts ongoing animations.
+ - tweak: The pull animation now supports diagonal directions (currently only applies
+ to the initial grab! pull code is spaghetti)
+ - bugfix: All screenshake sources now fully support the screenshake pref
+ - code_imp: cit_screenshake.dm has been fully merged into the base files.
+ - bugfix: You can no longer remotely apply fingerprints to storage objects by clicking
+ and dragging it around. Additionally, storage objects now rustle again when
+ clicking and dragging (only took like,, a year to fix)
+ - bugfix: The pickup animation now properly slides into your spaceman again, instead
+ of just kinda disappearing.
+ - tweak: When pulling a resting mob, they'll now skip the laying animation entirely,
+ fixing a visual oddity where they shrink and grow to flip.
+ - tweak: Alerts are now a little snappier and bouncier, as they've been swapped
+ from sine easing, to back easing.
+ - tweak: Radial menus now use sine easing, rather than linear easing. This just
+ looks a little prettier.
+ - tweak: Runechat now properly respects an object's X offset. Previously, it relied
+ on a hardcoded check for dogborgs.
+ - tweak: The float animation now uses pixel_z instead of pixel_y, fixing issues
+ where the Y offset gets wiped due to the float animation. This also makes floating
+ fully compatible with ctrl+WASD."
+ SandPoot:
+ - refactor: Does some extremely minor touches on pulling/pushing code.
+ timothyteakettle:
+ - rscadd: updates existing poly maid outfit with tg sprite but polychromatic
+ - rscadd: adds polychromic maid apron, gloves, collar, headband
+ - rscadd: adds support for polychromic accessories
diff --git a/icons/mob/clothing/accessories.dmi b/icons/mob/clothing/accessories.dmi
index 03849efa5a..f801c483f1 100644
Binary files a/icons/mob/clothing/accessories.dmi and b/icons/mob/clothing/accessories.dmi differ
diff --git a/icons/mob/clothing/hands.dmi b/icons/mob/clothing/hands.dmi
index ca8a7312fa..9bd206e04e 100644
Binary files a/icons/mob/clothing/hands.dmi and b/icons/mob/clothing/hands.dmi differ
diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi
index 20b8576277..2b317737d7 100644
Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ
diff --git a/icons/mob/clothing/uniform.dmi b/icons/mob/clothing/uniform.dmi
index 04d9b20a75..ce25963360 100644
Binary files a/icons/mob/clothing/uniform.dmi and b/icons/mob/clothing/uniform.dmi differ
diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi
index 79cb2bff77..f633f030c3 100644
Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ
diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi
index d4cd4b4f2f..17073805c9 100644
Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ
diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi
index 8540b2f392..c9491af6b2 100644
Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ
diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi
index c16b416cd8..de7dd234b1 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/modular_citadel/code/game/objects/cit_screenshake.dm b/modular_citadel/code/game/objects/cit_screenshake.dm
deleted file mode 100644
index 222de37f82..0000000000
--- a/modular_citadel/code/game/objects/cit_screenshake.dm
+++ /dev/null
@@ -1,51 +0,0 @@
-//we vlambeer now
-
-/obj/proc/shake_camera(mob/M, duration, strength=1)//byond's wonky with this shit
- set waitfor = FALSE
- if(!M || !M.client || duration <= 0)
- return
- var/client/C = M.client
- if (C.prefs.screenshake==0)
- return
- var/oldx = C.pixel_x
- var/oldy = C.pixel_y
- var/clientscreenshake = (C.prefs.screenshake * 0.01)
- var/max = (strength*clientscreenshake) * world.icon_size
- var/min = -((strength*clientscreenshake) * world.icon_size)
-
- for(var/i in 0 to duration-1)
- if (i == 0)
- animate(C, pixel_x=rand(min,max), pixel_y=rand(min,max), time=1)
- else
- animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1)
- animate(pixel_x=oldx, pixel_y=oldy, time=1)
-
-/obj/item/gun/energy
- recoil = 0.1
-
-/obj/item/gun/energy/kinetic_accelerator
- recoil = 0.5
-
-/obj/item/gun/ballistic
- recoil = 0.25
-
-/obj/item/gun/ballistic/shotgun
- recoil = 1
-
-/obj/item/gun/ballistic/revolver
- recoil = 0.5
-
-/obj/item/gun/ballistic/revolver/doublebarrel
- recoil = 1
-
-/obj/item/gun/syringe
- recoil = 0.1
-
-/obj/item/pneumatic_cannon/fire_items(turf/target, mob/user)
- . = ..()
- shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75))
-
-/obj/item/attack_obj(obj/O, mob/living/user)
- . = ..()
- if(force >= 20)
- shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01))
diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm
index 3824993009..0573a1a22a 100644
--- a/modular_citadel/code/modules/client/loadout/backpack.dm
+++ b/modular_citadel/code/modules/client/loadout/backpack.dm
@@ -175,3 +175,9 @@
/datum/gear/backpack/necklace//this is here because loadout doesn't support proper accessories
name = "A renameable necklace"
path = /obj/item/clothing/accessory/necklace
+
+/datum/gear/backpack/polymaidapron //this is ALSO here because loadout doesn't support proper accessories
+ name = "Polychromic maid apron"
+ path = /obj/item/clothing/accessory/maidapron/polychromic
+ loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC
+ loadout_initial_colors = list("#333333", "#FFFFFF")
diff --git a/modular_citadel/code/modules/client/loadout/gloves.dm b/modular_citadel/code/modules/client/loadout/gloves.dm
index 0b87ec65e6..766c6a7cac 100644
--- a/modular_citadel/code/modules/client/loadout/gloves.dm
+++ b/modular_citadel/code/modules/client/loadout/gloves.dm
@@ -13,3 +13,9 @@
/datum/gear/gloves/midnight
name = "Midnight gloves"
path = /obj/item/clothing/gloves/evening/black
+
+/datum/gear/gloves/maidpoly // WHAT DO YOU EVEN CALL THEM
+ name = "Polychromic maid gloves"
+ path = /obj/item/clothing/gloves/polymaid
+ loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC
+ loadout_initial_colors = list("#333333", "#FFFFFF")
diff --git a/modular_citadel/code/modules/client/loadout/head.dm b/modular_citadel/code/modules/client/loadout/head.dm
index f2a7ead5be..d0563d2986 100644
--- a/modular_citadel/code/modules/client/loadout/head.dm
+++ b/modular_citadel/code/modules/client/loadout/head.dm
@@ -58,6 +58,12 @@
name = "Maid headband"
path= /obj/item/clothing/head/maid
+/datum/gear/head/maidband/poly
+ name = "Polychromic maid headband"
+ path= /obj/item/clothing/head/maid/polychromic
+ loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC
+ loadout_initial_colors = list("#333333", "#FFFFFF")
+
/datum/gear/head/flakhelm
name = "Flak Helmet"
path = /obj/item/clothing/head/flakhelm
diff --git a/modular_citadel/code/modules/client/loadout/neck.dm b/modular_citadel/code/modules/client/loadout/neck.dm
index dc7735de2b..64d1fcdc1f 100644
--- a/modular_citadel/code/modules/client/loadout/neck.dm
+++ b/modular_citadel/code/modules/client/loadout/neck.dm
@@ -106,3 +106,9 @@
path = /obj/item/clothing/neck/cloak/cancloak/polychromic
loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC
loadout_initial_colors = list("#585858", "#373737", "#BEBEBE")
+
+/datum/gear/neck/maid
+ name = "Polychromatic Maid Collar"
+ path = /obj/item/clothing/neck/maid
+ loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC
+ loadout_initial_colors = list("#333333", "#FFFFFF")
diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm
index 4404d70bcd..c0c7846112 100644
--- a/modular_citadel/code/modules/client/loadout/uniform.dm
+++ b/modular_citadel/code/modules/client/loadout/uniform.dm
@@ -52,7 +52,7 @@
name = "Polychromic maid costume"
path = /obj/item/clothing/under/rank/civilian/janitor/maid/polychromic
loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC
- loadout_initial_colors = list("#FFFFFF", "#000000")
+ loadout_initial_colors = list("#333333", "#FFFFFF")
/datum/gear/uniform/mailmanuniform
name = "Mailman's jumpsuit"
diff --git a/modular_sand/code/modules/clothing/gloves/_gloves.dm b/modular_sand/code/modules/clothing/gloves/_gloves.dm
index b1984e9770..65f7de4825 100644
--- a/modular_sand/code/modules/clothing/gloves/_gloves.dm
+++ b/modular_sand/code/modules/clothing/gloves/_gloves.dm
@@ -1,16 +1,14 @@
/obj/item/clothing/gloves
var/dummy_thick = FALSE // is able to hold accessories on its item
- // Sandstorm edit - Removed the old attached accessory system. We use a list of accessories instead.
- var/list/obj/item/clothing/accessory/ring/attached_accessories = list()
var/max_accessories = 1
- // Sandstorm edit END
- var/mutable_appearance/accessory_overlay
+ var/list/obj/item/clothing/accessory/ring/attached_accessories = list()
+ var/list/mutable_appearance/accessory_overlays = list()
/obj/item/clothing/gloves/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
- if(accessory_overlay)
- . += accessory_overlay
+ if(length(accessory_overlays))
+ . += accessory_overlays
/obj/item/clothing/gloves/attackby(obj/item/I, mob/user, params)
if(!attach_accessory(I, user))
@@ -20,7 +18,7 @@
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
- if(length(attached_accessories)) // Sandstorm edit
+ if(length(attached_accessories))
remove_accessory(user)
/obj/item/clothing/gloves/equipped(mob/user, slot)
@@ -70,14 +68,16 @@
if((flags_inv & HIDEACCESSORY) || (A.flags_inv & HIDEACCESSORY))
return TRUE
- // Sandstorm edit
- accessory_overlay = mutable_appearance(I.mob_overlay_icon, I.item_state)
- for(var/obj/item/clothing/accessory/ring/attached_accessory in attached_accessories)
- var/mutable_appearance/Y = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.icon_state, ABOVE_HUD_LAYER)
- Y.alpha = attached_accessory.alpha
- Y.color = attached_accessory.color
- accessory_overlay.add_overlay(Y)
- // Sandstorm edit END
+ accessory_overlays = list(mutable_appearance('icons/mob/clothing/accessories.dmi', "blank"))
+ for(var/obj/item/clothing/accessory/attached_accessory in attached_accessories)
+ var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays")
+ if(!polychromic)
+ var/mutable_appearance/accessory_overlay = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, ABOVE_HUD_LAYER)
+ accessory_overlay.alpha = attached_accessory.alpha
+ accessory_overlay.color = attached_accessory.color
+ accessory_overlays += accessory_overlay
+ else
+ polychromic.apply_worn_overlays(attached_accessory, FALSE, attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, NONE, accessory_overlays)
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
@@ -91,10 +91,8 @@
if(!can_use(user))
return
- // Sandstorm edit
if(length(attached_accessories))
var/obj/item/clothing/accessory/ring/A = attached_accessories[length(attached_accessories)]
- // Sandstorm edit END
A.detach(src, user)
if(user.put_in_hands(A))
to_chat(user, "You detach [A] from [src].")
diff --git a/tgstation.dme b/tgstation.dme
index b4790e2cba..d2432fc40b 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -154,6 +154,8 @@
#include "code\__DEFINES\dcs\helpers.dm"
#include "code\__DEFINES\dcs\signals.dm"
#include "code\__DEFINES\dcs\signals\signals_subsystem.dm"
+#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movement.dm"
+#include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_living.dm"
#include "code\__DEFINES\mapping\maploader.dm"
#include "code\__DEFINES\material\worth.dm"
#include "code\__DEFINES\mobs\innate_abilities.dm"
@@ -3805,7 +3807,6 @@
#include "interface\skin.dmf"
#include "modular_citadel\code\datums\components\souldeath.dm"
#include "modular_citadel\code\datums\status_effects\chems.dm"
-#include "modular_citadel\code\game\objects\cit_screenshake.dm"
#include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm"
#include "modular_citadel\code\modules\admin\holder2.dm"
#include "modular_citadel\code\modules\admin\secrets.dm"