diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm
index 2e42957aa3a08..586a67e23954c 100644
--- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm
+++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm
@@ -145,3 +145,6 @@
/// From whoever has been revealed (atom/revealed)
#define COMSIG_ATOM_REVEAL "atom_reveal"
+
+/// From /atom/proc/set_density(new_value) for when an atom changes density
+#define COMSIG_ATOM_DENSITY_CHANGED "atom_density_change"
diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm
index 42f2d5fc31fee..7e1ba820dd8b7 100644
--- a/code/__DEFINES/tgs.dm
+++ b/code/__DEFINES/tgs.dm
@@ -1,7 +1,7 @@
// tgstation-server DMAPI
// The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in IETF RFC 2119.
-#define TGS_DMAPI_VERSION "7.3.0"
+#define TGS_DMAPI_VERSION "7.3.1"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
@@ -58,6 +58,11 @@
#define TGS_FILE2TEXT_NATIVE file2text
#endif
+// SpacemanDMM compatibility
+#ifndef CAN_BE_REDEFINED
+#define CAN_BE_REDEFINED(X)
+#endif
+
// EVENT CODES
/// Before a reboot mode change, extras parameters are the current and new reboot mode enums.
@@ -160,6 +165,7 @@
* * http_handler - Optional user defined [/datum/tgs_http_handler].
*/
/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE, datum/tgs_http_handler/http_handler)
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -170,6 +176,7 @@
* This function should not be called before ..() in [/world/proc/New].
*/
/world/proc/TgsInitializationComplete()
+ CAN_BE_REDEFINED(TRUE)
return
/// Consumers MUST run this macro at the start of [/world/proc/Topic].
@@ -177,6 +184,7 @@
/// Consumers MUST call this as late as possible in [world/proc/Reboot] (BEFORE ..()).
/world/proc/TgsReboot()
+ CAN_BE_REDEFINED(TRUE)
return
// DATUM DEFINITIONS
@@ -214,6 +222,7 @@
* Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards.
*/
/datum/tgs_version/proc/Wildcard()
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -222,6 +231,7 @@
* other_version - The [/datum/tgs_version] to compare against.
*/
/datum/tgs_version/proc/Equals(datum/tgs_version/other_version)
+ CAN_BE_REDEFINED(TRUE)
return
/// Represents a merge of a GitHub pull request.
@@ -459,16 +469,19 @@
/// Returns the maximum supported [/datum/tgs_version] of the DMAPI.
/world/proc/TgsMaximumApiVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the minimum supported [/datum/tgs_version] of the DMAPI.
/world/proc/TgsMinimumApiVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/**
* Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise.
*/
/world/proc/TgsAvailable()
+ CAN_BE_REDEFINED(TRUE)
return
// No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called.
@@ -480,6 +493,7 @@
* If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again.
*/
/world/proc/TgsEndProcess()
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -490,6 +504,7 @@
* admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
*/
/world/proc/TgsTargetedChatBroadcast(datum/tgs_message_content/message, admin_only = FALSE)
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -500,6 +515,7 @@
* user: The [/datum/tgs_chat_user] to PM.
*/
/world/proc/TgsChatPrivateMessage(datum/tgs_message_content/message, datum/tgs_chat_user/user)
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -510,42 +526,52 @@
* channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
*/
/world/proc/TgsChatBroadcast(datum/tgs_message_content/message, list/channels = null)
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the running engine type
/world/proc/TgsEngine()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsApiVersion()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the name of the TGS instance running the game if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsInstanceName()
+ CAN_BE_REDEFINED(TRUE)
return
/// Return the current [/datum/tgs_revision_information] of the running server if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsRevision()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current BYOND security level as a TGS_SECURITY_ define if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsSecurityLevel()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns the current BYOND visibility level as a TGS_VISIBILITY_ define if TGS is present, null otherwise. Requires TGS to be using interop API version 5 or higher otherwise the string "___unimplemented" wil be returned. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsVisibility()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsTestMerges()
+ CAN_BE_REDEFINED(TRUE)
return
/// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsChatChannelInfo()
+ CAN_BE_REDEFINED(TRUE)
return
/**
@@ -556,6 +582,7 @@
* wait_for_completion - If set, this function will not return until the event has run to completion.
*/
/world/proc/TgsTriggerEvent(event_name, list/parameters, wait_for_completion = FALSE)
+ CAN_BE_REDEFINED(TRUE)
return
/*
diff --git a/code/datums/components/ground_sinking.dm b/code/datums/components/ground_sinking.dm
index d29e84908a438..4e846b4cf704e 100644
--- a/code/datums/components/ground_sinking.dm
+++ b/code/datums/components/ground_sinking.dm
@@ -99,7 +99,7 @@
/datum/component/ground_sinking/proc/finish_sinking(mob/living/basic/living_target)
sinked = TRUE
is_sinking = FALSE
- living_target.density = FALSE
+ living_target.set_density(FALSE)
living_target.damage_coeff = damage_res_sinked
if(heal_when_sinked)
start_regenerating()
@@ -113,7 +113,7 @@
stop_regenerating()
living_target.icon_state = target_icon_state
living_target.damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1)
- living_target.density = TRUE
+ living_target.set_density(TRUE)
sinked = FALSE
/// The mop starts regaining health
diff --git a/code/datums/components/leanable.dm b/code/datums/components/leanable.dm
index b823cf5ec503c..bc0994dcdcd9d 100644
--- a/code/datums/components/leanable.dm
+++ b/code/datums/components/leanable.dm
@@ -4,6 +4,8 @@
var/leaning_offset = 11
/// List of mobs currently leaning on our parent
var/list/leaning_mobs = list()
+ /// Is this object currently leanable?
+ var/is_currently_leanable = TRUE
/datum/component/leanable/Initialize(mob/living/leaner, leaning_offset = 11)
. = ..()
@@ -13,15 +15,32 @@
/datum/component/leanable/RegisterWithParent()
RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, PROC_REF(mousedrop_receive))
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
+ RegisterSignal(parent, COMSIG_ATOM_DENSITY_CHANGED, PROC_REF(on_density_change))
+ var/atom/leanable_atom = parent
+ is_currently_leanable = leanable_atom.density
+
+/datum/component/leanable/UnregisterFromParent()
+ . = ..()
+ UnregisterSignal(parent, list(
+ COMSIG_MOVABLE_MOVED,
+ COMSIG_MOUSEDROPPED_ONTO,
+ COMSIG_ATOM_DENSITY_CHANGED,
+ ))
/datum/component/leanable/UnregisterFromParent()
UnregisterSignal(parent, list(COMSIG_MOUSEDROPPED_ONTO, COMSIG_MOVABLE_MOVED))
/datum/component/leanable/Destroy(force)
+ stop_leaning_leaners()
+ return ..()
+
+/datum/component/leanable/proc/stop_leaning_leaners(fall)
for (var/mob/living/leaner as anything in leaning_mobs)
leaner.stop_leaning()
+ if(fall)
+ to_chat(leaner, span_danger("You lose balance!"))
+ leaner.Paralyze(0.5 SECONDS)
leaning_mobs = null
- return ..()
/datum/component/leanable/proc/on_moved(datum/source)
SIGNAL_HANDLER
@@ -42,6 +61,8 @@
var/turf/checked_turf = get_step(leaner, REVERSE_DIR(leaner.dir))
if (checked_turf != get_turf(source))
return
+ if(!is_currently_leanable)
+ return COMPONENT_CANCEL_MOUSEDROPPED_ONTO
leaner.start_leaning(source, leaning_offset)
leaning_mobs += leaner
RegisterSignals(leaner, list(COMSIG_LIVING_STOPPED_LEANING, COMSIG_QDELETING), PROC_REF(stopped_leaning))
@@ -118,3 +139,11 @@
if (old_dir != new_dir)
INVOKE_ASYNC(src, PROC_REF(stop_leaning))
+
+/datum/component/leanable/proc/on_density_change()
+ SIGNAL_HANDLER
+ is_currently_leanable = !is_currently_leanable
+ if(!is_currently_leanable)
+ stop_leaning_leaners(fall = TRUE)
+ return
+ stop_leaning_leaners()
diff --git a/code/datums/components/pet_commands/pet_command.dm b/code/datums/components/pet_commands/pet_command.dm
index 97dfbc8b5cb18..84b288a5cd80a 100644
--- a/code/datums/components/pet_commands/pet_command.dm
+++ b/code/datums/components/pet_commands/pet_command.dm
@@ -174,13 +174,12 @@
SIGNAL_HANDLER
if(!can_see(source, target, 9))
return COMSIG_MOB_CANCEL_CLICKON
- on_target_set(source, target)
+ var/manual_emote_text = generate_emote_command(target)
+ if(on_target_set(source, target) && !isnull(manual_emote_text))
+ INVOKE_ASYNC(source, TYPE_PROC_REF(/atom, manual_emote), manual_emote_text)
UnregisterSignal(source, COMSIG_MOB_CLICKON)
source.client?.mouse_override_icon = source.client::mouse_override_icon
source.update_mouse_pointer()
- var/manual_emote_text = generate_emote_command(target)
- if(!isnull(manual_emote_text))
- INVOKE_ASYNC(source, TYPE_PROC_REF(/atom, manual_emote), manual_emote_text)
return COMSIG_MOB_CANCEL_CLICKON
/datum/pet_command/proc/point_on_target(mob/living/friend, atom/potential_target)
@@ -214,11 +213,12 @@
/datum/pet_command/proc/on_target_set(mob/living/friend, atom/potential_target)
var/mob/living/parent = weak_parent.resolve()
if (!parent)
- return
+ return FALSE
parent.ai_controller.CancelActions()
if(!look_for_target(friend, potential_target) || !set_command_target(parent, potential_target))
- return
+ return FALSE
parent.visible_message(span_warning("[parent] follows [friend]'s gesture towards [potential_target] [pointed_reaction]!"))
+ return TRUE
diff --git a/code/datums/components/pet_commands/pet_commands_basic.dm b/code/datums/components/pet_commands/pet_commands_basic.dm
index 1ac49ce9a9c05..cd535b33ecaba 100644
--- a/code/datums/components/pet_commands/pet_commands_basic.dm
+++ b/code/datums/components/pet_commands/pet_commands_basic.dm
@@ -147,16 +147,16 @@
// Refuse to target things we can't target, chiefly other friends
/datum/pet_command/attack/set_command_target(mob/living/parent, atom/target)
if (!target)
- return
+ return FALSE
var/mob/living/living_parent = parent
if (!living_parent.ai_controller)
- return
+ return FALSE
var/datum/targeting_strategy/targeter = GET_TARGETING_STRATEGY(living_parent.ai_controller.blackboard[targeting_strategy_key])
if (!targeter)
- return
+ return FALSE
if (!targeter.can_attack(living_parent, target))
refuse_target(parent, target)
- return
+ return FALSE
return ..()
/datum/pet_command/attack/retrieve_command_text(atom/living_pet, atom/target)
@@ -186,16 +186,16 @@
/datum/pet_command/breed/set_command_target(mob/living/parent, atom/target)
if(isnull(target) || !isliving(target))
- return
+ return FALSE
if(!HAS_TRAIT(parent, TRAIT_MOB_BREEDER) || !HAS_TRAIT(target, TRAIT_MOB_BREEDER))
- return
+ return FALSE
if(isnull(parent.ai_controller))
- return
+ return FALSE
if(!parent.ai_controller.blackboard[BB_BREED_READY] || isnull(parent.ai_controller.blackboard[BB_BABIES_PARTNER_TYPES]))
- return
+ return FALSE
var/mob/living/living_target = target
if(!living_target.ai_controller?.blackboard[BB_BREED_READY])
- return
+ return FALSE
return ..()
/datum/pet_command/breed/execute_action(datum/ai_controller/controller)
diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm
index c8c3111889eac..a7d057aa9fa4d 100644
--- a/code/game/atom/_atom.dm
+++ b/code/game/atom/_atom.dm
@@ -722,7 +722,7 @@
return
. = density
density = new_value
-
+ SEND_SIGNAL(src, COMSIG_ATOM_DENSITY_CHANGED)
///Setter for the `base_pixel_x` variable to append behavior related to its changing.
/atom/proc/set_base_pixel_x(new_value)
diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm
index 9e089eeaf2be8..3b01c40403d8c 100644
--- a/code/game/machinery/airlock_control.dm
+++ b/code/game/machinery/airlock_control.dm
@@ -6,6 +6,14 @@
var/airlock_state
var/frequency
+
+/obj/machinery/door/airlock/mouse_drop_receive(mob/living/dropping, mob/user, params)
+ . = ..()
+ // We add the component only once here & not in Initialize() because there are tons of airlocks & we don't want to add to their init times
+ // This is on airlock rather than on door because windoors are door and leaning looks whack on windoors
+ LoadComponent(/datum/component/leanable, dropping)
+
+
/// Forces the airlock to unbolt and open
/obj/machinery/door/airlock/proc/secure_open()
locked = FALSE
diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm
index d51e197a0bcdd..6aa3368341215 100644
--- a/code/game/machinery/computer/_computer.dm
+++ b/code/game/machinery/computer/_computer.dm
@@ -30,6 +30,11 @@
. = ..()
power_change()
+/obj/machinery/computer/mouse_drop_receive(mob/living/dropping, mob/user, params)
+ . = ..()
+ // We add the component only once here & not in Initialize() because there are tons of computers & we don't want to add to their init times
+ LoadComponent(/datum/component/leanable, dropping)
+
/obj/machinery/computer/CanAllowThrough(atom/movable/mover, border_dir) // allows projectiles to fly over the computer
. = ..()
if(.)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index d57714c1cf32c..b562713fe3713 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -1355,7 +1355,7 @@
if(air_tight)
set_density(TRUE)
if(multi_tile)
- filler.density = TRUE
+ filler.set_density(TRUE)
flags_1 |= PREVENT_CLICK_UNDER_1
air_update_turf(TRUE, TRUE)
var/unpassable_delay = animation_segment_delay(AIRLOCK_CLOSING_UNPASSABLE)
@@ -1363,7 +1363,7 @@
if(!air_tight)
set_density(TRUE)
if(multi_tile)
- filler.density = TRUE
+ filler.set_density(TRUE)
flags_1 |= PREVENT_CLICK_UNDER_1
air_update_turf(TRUE, TRUE)
var/opaque_delay = animation_segment_delay(AIRLOCK_CLOSING_OPAQUE) - unpassable_delay
diff --git a/code/game/machinery/modular_shield.dm b/code/game/machinery/modular_shield.dm
index b4fa6bed17bb0..2e8fa632e42bf 100644
--- a/code/game/machinery/modular_shield.dm
+++ b/code/game/machinery/modular_shield.dm
@@ -240,7 +240,7 @@
/obj/machinery/modular_shield_generator/proc/finish_field()
for(var/obj/structure/emergency_shield/modular/current_shield in deployed_shields)
- current_shield.density = TRUE
+ current_shield.set_density(TRUE)
current_shield.alpha = 255
initiating = FALSE
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index 4a5ee234c7742..cef73b0fbfd88 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -77,10 +77,13 @@
icon_state = "ai-empty"
anchored = TRUE
state = AI_READY_CORE
+ var/mob/living/silicon/ai/attached_ai
-/obj/structure/ai_core/deactivated/Initialize(mapload, skip_mmi_creation = FALSE, posibrain = FALSE)
+/obj/structure/ai_core/deactivated/Initialize(mapload, skip_mmi_creation = FALSE, posibrain = FALSE, linked_ai)
. = ..()
circuit = new(src)
+ if(linked_ai)
+ attached_ai = linked_ai
if(skip_mmi_creation)
return
if(posibrain)
@@ -90,6 +93,16 @@
core_mmi.brain = new(core_mmi)
core_mmi.update_appearance()
+/obj/structure/ai_core/deactivated/Destroy()
+ if(attached_ai)
+ attached_ai.linked_core = null
+ attached_ai = null
+ . = ..()
+
+/obj/structure/ai_core/deactivated/proc/disable_doomsday(datum/source)
+ SIGNAL_HANDLER
+ attached_ai.ShutOffDoomsdayDevice()
+
/obj/structure/ai_core/latejoin_inactive
name = "networked AI core"
desc = "This AI core is connected by bluespace transmitters to NTNet, allowing for an AI personality to be downloaded to it on the fly mid-shift."
diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm
index 402d24c6c830d..3937ed55710f5 100644
--- a/code/game/turfs/closed/walls.dm
+++ b/code/game/turfs/closed/walls.dm
@@ -49,6 +49,14 @@
underlay_appearance.icon_state = fixed_underlay["icon_state"]
fixed_underlay = string_assoc_list(fixed_underlay)
underlays += underlay_appearance
+ register_context()
+
+/turf/closed/wall/add_context(atom/source, list/context, obj/item/held_item, mob/user)
+ . = NONE
+ if(!isnull(held_item))
+ if((initial(smoothing_flags) & SMOOTH_DIAGONAL_CORNERS) && held_item.tool_behaviour == TOOL_WRENCH)
+ context[SCREENTIP_CONTEXT_LMB] = "Adjust Wall Corner"
+ return CONTEXTUAL_SCREENTIP_SET
/turf/closed/wall/mouse_drop_receive(atom/dropping, mob/user, params)
//Adds the component only once. We do it here & not in Initialize() because there are tons of walls & we don't want to add to their init times
@@ -64,7 +72,9 @@
return ..()
/turf/closed/wall/examine(mob/user)
- . += ..()
+ . = ..()
+ if(initial(smoothing_flags) & SMOOTH_DIAGONAL_CORNERS)
+ . += span_notice("You could adjust its corners with a wrench.")
. += deconstruction_hints(user)
/turf/closed/wall/proc/deconstruction_hints(mob/user)
@@ -324,3 +334,15 @@
/turf/closed/wall/Exited(atom/movable/gone, direction)
. = ..()
SEND_SIGNAL(gone, COMSIG_LIVING_WALL_EXITED, src)
+
+/turf/closed/wall/wrench_act(mob/living/user, obj/item/tool)
+ if(user.combat_mode || !(initial(smoothing_flags) & SMOOTH_DIAGONAL_CORNERS))
+ return ITEM_INTERACT_SKIP_TO_ATTACK
+ if(smoothing_flags & SMOOTH_DIAGONAL_CORNERS)
+ smoothing_flags &= ~SMOOTH_DIAGONAL_CORNERS
+ else
+ smoothing_flags |= SMOOTH_DIAGONAL_CORNERS
+ QUEUE_SMOOTH(src)
+ to_chat(user, span_notice("You adjust [src]."))
+ tool.play_tool_sound(src)
+ return ITEM_INTERACT_SUCCESS
diff --git a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm
index 54d393780b25b..7215bdf3ae85f 100644
--- a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm
+++ b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm
@@ -22,8 +22,7 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/
var/message_living = null
/// Stores world.time to figure out when to next give resources
var/resource_delay = 0
- /// For blob-mobs and extinguishing-based effects
- var/fire_based = FALSE
+ ///The blob overmind eye mob used to control the spread
var/mob/eye/blob/overmind
/// The amount of health regenned on core_process
var/base_core_regen = BLOB_CORE_HP_REGEN
diff --git a/code/modules/antagonists/blob/blobstrains/blazing_oil.dm b/code/modules/antagonists/blob/blobstrains/blazing_oil.dm
index f01f2c2faadc6..c33d0b6e92961 100644
--- a/code/modules/antagonists/blob/blobstrains/blazing_oil.dm
+++ b/code/modules/antagonists/blob/blobstrains/blazing_oil.dm
@@ -12,7 +12,6 @@
message = "The blob splashes you with burning oil"
message_living = ", and you feel your skin char and melt"
reagent = /datum/reagent/blob/blazing_oil
- fire_based = TRUE
/datum/blobstrain/reagent/blazing_oil/extinguish_reaction(obj/structure/blob/B)
B.take_damage(4.5, BURN, ENERGY)
diff --git a/code/modules/antagonists/heretic/status_effects/buffs.dm b/code/modules/antagonists/heretic/status_effects/buffs.dm
index 362e9750b49c1..d42626871bbff 100644
--- a/code/modules/antagonists/heretic/status_effects/buffs.dm
+++ b/code/modules/antagonists/heretic/status_effects/buffs.dm
@@ -284,7 +284,7 @@
/datum/status_effect/caretaker_refuge/on_apply()
animate(owner, alpha = 45,time = 0.5 SECONDS)
- owner.density = FALSE
+ owner.set_density(FALSE)
RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_ALLOW_HERETIC_CASTING), PROC_REF(on_focus_lost))
RegisterSignal(owner, COMSIG_MOB_BEFORE_SPELL_CAST, PROC_REF(prevent_spell_usage))
RegisterSignal(owner, COMSIG_ATOM_HOLYATTACK, PROC_REF(nullrod_handler))
diff --git a/code/modules/antagonists/malf_ai/malf_ai_modules.dm b/code/modules/antagonists/malf_ai/malf_ai_modules.dm
index 65d12fcb25ac4..00b581bcebf5a 100644
--- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm
+++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm
@@ -904,12 +904,12 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
/datum/ai_module/malf/upgrade/mecha_domination
name = "Unlock Mech Domination"
description = "Allows you to hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. \
- Do not allow the mech to leave the station's vicinity or allow it to be destroyed. \
- Upgrade is done immediately upon purchase."
+ Upgrade is done immediately upon purchase. Do not allow the mech to leave the station's vicinity or allow it to be destroyed. \
+ If your core is destroyed, you will be lose connection with the Doomsday Device and the countdown will cease."
cost = 30
upgrade = TRUE
unlock_text = span_notice("Virus package compiled. Select a target mech at any time. You must remain on the station at all times. \
- Loss of signal will result in total system lockout.")
+ Loss of signal will result in total system lockout. If your inactive core is destroyed, you will be lose connection with the Doomsday Device and the countdown will cease.")
unlock_sound = 'sound/vehicles/mecha/nominal.ogg'
/datum/ai_module/malf/upgrade/mecha_domination/upgrade(mob/living/silicon/ai/AI)
diff --git a/code/modules/antagonists/nukeop/equipment/pinpointer.dm b/code/modules/antagonists/nukeop/equipment/pinpointer.dm
index 82113fb31be2b..ebdbdbe86980b 100644
--- a/code/modules/antagonists/nukeop/equipment/pinpointer.dm
+++ b/code/modules/antagonists/nukeop/equipment/pinpointer.dm
@@ -43,7 +43,10 @@
for(var/V in GLOB.ai_list)
var/mob/living/silicon/ai/A = V
if(A.nuking)
- target = A
+ if(A.linked_core)
+ target = A.linked_core
+ else
+ target = A
for(var/obj/machinery/power/apc/apc as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/power/apc))
if(apc.malfhack && apc.occupier)
target = apc
diff --git a/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm b/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm
index 0a6a4b03b4354..922289698d4d5 100644
--- a/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm
+++ b/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm
@@ -210,11 +210,11 @@
/datum/pet_command/clean/set_command_target(mob/living/parent, atom/target)
if(isnull(target) || !istype(target, /obj/effect/decal/cleanable))
- return
+ return FALSE
if(isnull(parent.ai_controller))
- return
+ return FALSE
if(LAZYACCESS(parent.ai_controller.blackboard[BB_TEMPORARY_IGNORE_LIST], target))
- return
+ return FALSE
return ..()
/datum/pet_command/clean/execute_action(datum/ai_controller/basic_controller/bot/controller)
diff --git a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm
index 4b329a0003aa8..1028a7d45eb14 100644
--- a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm
@@ -131,7 +131,7 @@
/datum/pet_command/breed/gutlunch/set_command_target(mob/living/parent, atom/target)
if(GLOB.gutlunch_count >= MAXIMUM_GUTLUNCH_POP)
parent.balloon_alert_to_viewers("can't reproduce anymore!")
- return
+ return FALSE
return ..()
#undef MAXIMUM_GUTLUNCH_POP
diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
index 7e7d3e71819bf..b5c590a358968 100644
--- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
+++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm
@@ -268,7 +268,7 @@
/datum/pet_command/use_ability/lob_charge/set_command_target(mob/living/parent, atom/target)
if (!target)
- return
+ return FALSE
var/datum/targeting_strategy/targeter = GET_TARGETING_STRATEGY(parent.ai_controller.blackboard[targeting_strategy_key])
if(!targeter?.can_attack(parent, target))
parent.balloon_alert_to_viewers("shakes head!")
diff --git a/code/modules/mob/living/basic/minebots/minebot_ai.dm b/code/modules/mob/living/basic/minebots/minebot_ai.dm
index 39248a63295ae..a36ea26c4f27f 100644
--- a/code/modules/mob/living/basic/minebots/minebot_ai.dm
+++ b/code/modules/mob/living/basic/minebots/minebot_ai.dm
@@ -350,9 +350,10 @@
/datum/pet_command/protect_owner/minebot/set_command_target(mob/living/parent, atom/target)
if(!parent.ai_controller.blackboard[BB_MINEBOT_AUTO_DEFEND])
- return
+ return FALSE
if(!parent.ai_controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET) && !QDELETED(target)) //we are already dealing with something,
parent.ai_controller.set_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET, target)
+ return TRUE
/datum/pet_command/protect_owner/minebot/execute_action(datum/ai_controller/controller)
if(controller.blackboard[BB_MINEBOT_AUTO_DEFEND])
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index fcd73ec99bf1e..d974141bc19c8 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -162,7 +162,7 @@
new_paper.raw_stamp_data = copy_raw_stamps()
new_paper.stamp_cache = stamp_cache?.Copy()
new_paper.update_icon_state()
- copy_overlays(new_paper, TRUE)
+ new_paper.copy_overlays(src)
return new_paper
/**
diff --git a/code/modules/tgs/v5/undefs.dm b/code/modules/tgs/v5/undefs.dm
index acd19dfa6411c..ca49e46cdffad 100644
--- a/code/modules/tgs/v5/undefs.dm
+++ b/code/modules/tgs/v5/undefs.dm
@@ -18,6 +18,7 @@
#undef DMAPI5_PARAMETER_ACCESS_IDENTIFIER
#undef DMAPI5_PARAMETER_CUSTOM_COMMANDS
+#undef DMAPI5_PARAMETER_TOPIC_PORT
#undef DMAPI5_CHUNK
#undef DMAPI5_CHUNK_PAYLOAD
diff --git a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm
index dfcf2896b5b74..6395b39393ef8 100644
--- a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm
+++ b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm
@@ -145,7 +145,7 @@
chassis.mecha_flags |= QUIET_STEPS|QUIET_TURNS|CANNOT_INTERACT
chassis.phasing = "flying"
chassis.movedelay = 1
- chassis.density = FALSE
+ chassis.set_density(FALSE)
chassis.layer = ABOVE_ALL_MOB_LAYER
animate(chassis, alpha = 0, time = 8, easing = QUAD_EASING|EASE_IN, flags = ANIMATION_PARALLEL)
animate(chassis, pixel_z = 400, time = 10, easing = QUAD_EASING|EASE_IN, flags = ANIMATION_PARALLEL) //Animate our rising mech (just like pods hehe)
@@ -176,7 +176,7 @@
chassis.mecha_flags &= ~(QUIET_STEPS|QUIET_TURNS|CANNOT_INTERACT)
chassis.phasing = initial(chassis.phasing)
chassis.movedelay = initial(chassis.movedelay)
- chassis.density = TRUE
+ chassis.set_density(TRUE)
chassis.layer = initial(chassis.layer)
SET_PLANE(chassis, initial(chassis.plane), landed_on)
skyfall_charge_level = 0
diff --git a/code/modules/vehicles/mecha/mecha_ai_interaction.dm b/code/modules/vehicles/mecha/mecha_ai_interaction.dm
index 4b4d92f06a268..f43a11903a950 100644
--- a/code/modules/vehicles/mecha/mecha_ai_interaction.dm
+++ b/code/modules/vehicles/mecha/mecha_ai_interaction.dm
@@ -66,7 +66,9 @@
return
if(AI_MECH_HACK) //Called by AIs on the mech
- AI.linked_core = new /obj/structure/ai_core/deactivated(AI.loc)
+ var/obj/structure/ai_core/deactivated/deactivated_core = new(AI.loc, FALSE, FALSE, AI)
+ AI.linked_core = deactivated_core
+ AI.linked_core.RegisterSignal(deactivated_core, COMSIG_ATOM_DESTRUCTION, TYPE_PROC_REF(/obj/structure/ai_core/deactivated, disable_doomsday)) //Protect that core! The structure goes bye-bye when we re-shunt back in so no need for cleanup.
AI.linked_core.remote_ai = AI
if(AI.can_dominate_mechs && LAZYLEN(occupants)) //Oh, I am sorry, were you using that?
to_chat(AI, span_warning("Occupants detected! Forced ejection initiated!"))
diff --git a/html/changelogs/AutoChangeLog-pr-88517.yml b/html/changelogs/AutoChangeLog-pr-88517.yml
deleted file mode 100644
index 09cc1464332bb..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88517.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "timothymtorres"
-delete-after: True
-changes:
- - refactor: "Sound has been heavily optimized and will now ignore low volume sounds from far away."
- - admin: "Add debugging sound earmuffs to admin equipment inside the debug box. Wear them to determine a sounds max range, distance, volume, and sound name. Highly recommended to walk otherwise you will get spammed with footstep sounds."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88626.yml b/html/changelogs/AutoChangeLog-pr-88626.yml
deleted file mode 100644
index c80e885bb1c3b..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88626.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "FlufflesTheDog"
-delete-after: True
-changes:
- - bugfix: "welding sparks no longer break on transitioning to a different floor"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88629.yml b/html/changelogs/AutoChangeLog-pr-88629.yml
deleted file mode 100644
index 4e2c70f2091d3..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88629.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "SyncIt21"
-delete-after: True
-changes:
- - bugfix: "Changing gather mode on storage items won't drop it's stored items"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88630.yml b/html/changelogs/AutoChangeLog-pr-88630.yml
deleted file mode 100644
index 237753042fd2e..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88630.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "necromanceranne"
-delete-after: True
-changes:
- - bugfix: "Tackling resulting in a neutral outcome does not force you to the floor."
- - bugfix: "Getting up is now properly influenced by spinal implants."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88664.yml b/html/changelogs/AutoChangeLog-pr-88664.yml
deleted file mode 100644
index c0c6abf8ee972..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88664.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "SmArtKar"
-delete-after: True
-changes:
- - bugfix: "Fixed podperson hair not updating"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88674.yml b/html/changelogs/AutoChangeLog-pr-88674.yml
deleted file mode 100644
index dba55e1ebec70..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88674.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "SmArtKar"
-delete-after: True
-changes:
- - qol: "Iron material tiles can now be used to tile lattice to make plating"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88734.yml b/html/changelogs/AutoChangeLog-pr-88734.yml
deleted file mode 100644
index d9f0053130f73..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88734.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "LT3"
-delete-after: True
-changes:
- - bugfix: "Fixed lead acid cell having extremely high max charge"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88738.yml b/html/changelogs/AutoChangeLog-pr-88738.yml
deleted file mode 100644
index 32429563b9a8a..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88738.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Paxilmaniac"
-delete-after: True
-changes:
- - bugfix: "fixes crafting menu-made rice dough being unusable for bread"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88739.yml b/html/changelogs/AutoChangeLog-pr-88739.yml
deleted file mode 100644
index c75e4db55840b..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88739.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "SyncIt21"
-delete-after: True
-changes:
- - bugfix: "Fixes shattering element dropping stuff on blocked turfs"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88742.yml b/html/changelogs/AutoChangeLog-pr-88742.yml
deleted file mode 100644
index 44a62dfd220c1..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88742.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "00-Steven"
-delete-after: True
-changes:
- - spellcheck: "Give alert 'examiante' > 'examine'."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88744.yml b/html/changelogs/AutoChangeLog-pr-88744.yml
deleted file mode 100644
index a9933a7c174ed..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88744.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Absolucy"
-delete-after: True
-changes:
- - code_imp: "Very slightly improved the performance of code related to adding and removing traits."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-88745.yml b/html/changelogs/AutoChangeLog-pr-88745.yml
deleted file mode 100644
index 60558e29d938b..0000000000000
--- a/html/changelogs/AutoChangeLog-pr-88745.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "SmArtKar"
-delete-after: True
-changes:
- - bugfix: "Fixed chair, echair, wheelchair and vehicle overlays on painted objects"
\ No newline at end of file
diff --git a/html/changelogs/archive/2024-12.yml b/html/changelogs/archive/2024-12.yml
index a263bcf647d65..0a1a2e5323812 100644
--- a/html/changelogs/archive/2024-12.yml
+++ b/html/changelogs/archive/2024-12.yml
@@ -733,3 +733,48 @@
to other people, so don't be stupid!
- rscadd: influences cannot be bombed for fish.
- rscadd: Heretics can now infuse their fishing rod, and fish for knowledge.
+2024-12-29:
+ 00-Steven:
+ - spellcheck: Give alert 'examiante' > 'examine'.
+ Absolucy:
+ - code_imp: Very slightly improved the performance of code related to adding and
+ removing traits.
+ Ben10Omintrix:
+ - bugfix: radial pet commanding emotes will now not appear if the command is impossible
+ to execute
+ FlufflesTheDog:
+ - bugfix: welding sparks no longer break on transitioning to a different floor
+ LT3:
+ - bugfix: Fixed lead acid cell having extremely high max charge
+ Paxilmaniac:
+ - bugfix: fixes crafting menu-made rice dough being unusable for bread
+ SmArtKar:
+ - qol: Iron material tiles can now be used to tile lattice to make plating
+ - bugfix: Fixed podperson hair not updating
+ - bugfix: Fixed chair, echair, wheelchair and vehicle overlays on painted objects
+ SyncIt21:
+ - bugfix: Changing gather mode on storage items won't drop it's stored items
+ - bugfix: Fixes shattering element dropping stuff on blocked turfs
+ necromanceranne:
+ - bugfix: Tackling resulting in a neutral outcome does not force you to the floor.
+ - bugfix: Getting up is now properly influenced by spinal implants.
+ timothymtorres:
+ - refactor: Sound has been heavily optimized and will now ignore low volume sounds
+ from far away.
+ - admin: Add debugging sound earmuffs to admin equipment inside the debug box. Wear
+ them to determine a sounds max range, distance, volume, and sound name. Highly
+ recommended to walk otherwise you will get spammed with footstep sounds.
+2024-12-30:
+ 00-Steven:
+ - bugfix: Photocopying no longer removes the stamp overlays from the original paper,
+ and actually copies them to the copy.
+ Rhials:
+ - balance: When dominating a mech as a Malfunctioning AI, the core you shunted from
+ will disable your Doomsday Counterdown when destroyed. Make sure to protect
+ that core!
+ grungussuss:
+ - rscadd: computers and airlocks are now leanable
+ - refactor: changed how density/collision of some objects is changed, report any
+ oddities!
+ mc-oofert:
+ - qol: you can adjust diagonal walls to be not diagonal walls with a wrench