diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm
index c561a64ebf58..fdfec5e8ca08 100644
--- a/code/__DEFINES/tgs.dm
+++ b/code/__DEFINES/tgs.dm
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
-#define TGS_DMAPI_VERSION "7.0.1"
+#define TGS_DMAPI_VERSION "7.0.2"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
@@ -426,6 +426,7 @@
/**
* Send a message to connected chats. This function may sleep!
+ * If TGS is offline when called, the message may be placed in a queue to be sent and this function will return immediately. Your message will be sent when TGS reconnects to the game.
*
* message - The [/datum/tgs_message_content] to send.
* admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
@@ -435,6 +436,7 @@
/**
* Send a private message to a specific user. This function may sleep!
+ * If TGS is offline when called, the message may be placed in a queue to be sent and this function will return immediately. Your message will be sent when TGS reconnects to the game.
*
* message - The [/datum/tgs_message_content] to send.
* user: The [/datum/tgs_chat_user] to PM.
@@ -444,6 +446,7 @@
/**
* Send a message to connected chats that are flagged as game-related in TGS. This function may sleep!
+ * If TGS is offline when called, the message may be placed in a queue to be sent and this function will return immediately. Your message will be sent when TGS reconnects to the game.
*
* message - The [/datum/tgs_message_content] to send.
* channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
diff --git a/code/datums/balloon_alerts/balloon_alerts.dm b/code/datums/balloon_alerts/balloon_alerts.dm
index 8ef770fa9d7f..59f826fbe7d2 100644
--- a/code/datums/balloon_alerts/balloon_alerts.dm
+++ b/code/datums/balloon_alerts/balloon_alerts.dm
@@ -37,20 +37,15 @@
if (isnull(viewer_client))
return
- var/bound_width = world.icon_size
- if (ismovable(src))
- var/atom/movable/movable_source = src
- bound_width = movable_source.bound_width
-
var/image/balloon_alert = image(loc = get_atom_on_turf(src), layer = ABOVE_MOB_LAYER)
balloon_alert.plane = RUNECHAT_PLANE
balloon_alert.alpha = 0
balloon_alert.color = text_color
balloon_alert.appearance_flags = NO_CLIENT_COLOR|KEEP_APART|RESET_COLOR|RESET_TRANSFORM|RESET_ALPHA
balloon_alert.maptext = MAPTEXT("[text]")
- balloon_alert.maptext_x = (BALLOON_TEXT_WIDTH - bound_width) * -0.5
balloon_alert.maptext_height = WXH_TO_HEIGHT(viewer_client?.MeasureText(text, null, BALLOON_TEXT_WIDTH))
balloon_alert.maptext_width = BALLOON_TEXT_WIDTH
+ balloon_alert.maptext_x = get_maxptext_x_offset(balloon_alert)
if(appearance_flags & PIXEL_SCALE)
balloon_alert.appearance_flags |= PIXEL_SCALE
//"[text]"
diff --git a/code/datums/langchat/langchat.dm b/code/datums/langchat/langchat.dm
index 83b9be0ac053..b82b03b51774 100644
--- a/code/datums/langchat/langchat.dm
+++ b/code/datums/langchat/langchat.dm
@@ -47,12 +47,12 @@
M.client.images -= langchat_image
langchat_listeners = null
-/atom/proc/langchat_set_x_offset()
- langchat_image.maptext_x = world.icon_size / 2 - langchat_image.maptext_width / 2
-/atom/movable/langchat_set_x_offset()
- langchat_image.maptext_x = bound_width / 2 - langchat_image.maptext_width / 2
-/mob/langchat_set_x_offset()
- langchat_image.maptext_x = icon_size / 2 - langchat_image.maptext_width / 2
+/atom/proc/get_maxptext_x_offset(image/maptext_image)
+ return (world.icon_size / 2) - (maptext_image.maptext_width / 2)
+/atom/movable/get_maxptext_x_offset(image/maptext_image)
+ return (bound_width / 2) - (maptext_image.maptext_width / 2)
+/mob/get_maxptext_x_offset(image/maptext_image)
+ return (icon_size / 2) - (maptext_image.maptext_width / 2)
///Creates the image if one does not exist, resets settings that are modified by speech procs.
/atom/proc/langchat_make_image(override_color = null)
@@ -64,7 +64,7 @@
langchat_image.maptext_y = langchat_height
langchat_image.maptext_height = 64
langchat_image.maptext_y -= LANGCHAT_MESSAGE_POP_Y_SINK
- langchat_set_x_offset()
+ langchat_image.maptext_x = get_maxptext_x_offset(langchat_image)
langchat_image.pixel_y = 0
langchat_image.alpha = 0
@@ -109,7 +109,7 @@
langchat_image.maptext = text_to_display
langchat_image.maptext_width = LANGCHAT_WIDTH
- langchat_set_x_offset()
+ langchat_image.maptext_x = get_maxptext_x_offset(langchat_image)
langchat_listeners = listeners
for(var/mob/M in langchat_listeners)
@@ -156,7 +156,7 @@
langchat_image.maptext = text_to_display
langchat_image.maptext_width = LANGCHAT_WIDTH * 2
- langchat_set_x_offset()
+ langchat_image.maptext_x = get_maxptext_x_offset(langchat_image)
langchat_listeners = listeners
for(var/mob/M in langchat_listeners)
diff --git a/code/modules/cm_marines/smartgun_mount.dm b/code/modules/cm_marines/smartgun_mount.dm
index e307ef8a611b..dbfdf03e0b76 100644
--- a/code/modules/cm_marines/smartgun_mount.dm
+++ b/code/modules/cm_marines/smartgun_mount.dm
@@ -476,7 +476,6 @@
/// What firemodes this gun has
var/static/list/gun_firemodes = list(
GUN_FIREMODE_SEMIAUTO,
- GUN_FIREMODE_BURSTFIRE,
GUN_FIREMODE_AUTOMATIC,
)
/// A multiplier for how slow this gun should fire in automatic as opposed to burst. 1 is normal, 1.2 is 20% slower, 0.8 is 20% faster, etc.
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm
index ef084c9b5b59..bd01376c9f9d 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm
@@ -17,6 +17,8 @@
if(xeno.crest_defense)
to_chat(xeno, SPAN_XENOWARNING("We lower our crest."))
+ xeno.balloon_alert(xeno, "crest lowered")
+
xeno.ability_speed_modifier += speed_debuff
xeno.armor_deflection_buff += armor_buff
xeno.mob_size = MOB_SIZE_BIG //knockback immune
@@ -24,6 +26,8 @@
xeno.update_icons()
else
to_chat(xeno, SPAN_XENOWARNING("We raise our crest."))
+ xeno.balloon_alert(xeno, "crest raised")
+
xeno.ability_speed_modifier -= speed_debuff
xeno.armor_deflection_buff -= armor_buff
xeno.mob_size = MOB_SIZE_XENO //no longer knockback immune
@@ -313,4 +317,3 @@
/datum/action/xeno_action/onclick/soak/proc/remove_enrage()
owner.remove_filter("steelcrest_enraged")
-
diff --git a/code/modules/mob/living/carbon/xenomorph/hive_status.dm b/code/modules/mob/living/carbon/xenomorph/hive_status.dm
index ab812cba5c97..63aea4007482 100644
--- a/code/modules/mob/living/carbon/xenomorph/hive_status.dm
+++ b/code/modules/mob/living/carbon/xenomorph/hive_status.dm
@@ -779,7 +779,12 @@
spawning_area = pick(totalXenos) // FUCK IT JUST GO ANYWHERE
var/list/turf_list
for(var/turf/open/open_turf in orange(3, spawning_area))
+ if(istype(open_turf, /turf/open/space))
+ continue
LAZYADD(turf_list, open_turf)
+ // just on the off-chance
+ if(!LAZYLEN(turf_list))
+ return FALSE
var/turf/open/spawning_turf = pick(turf_list)
var/mob/living/carbon/xenomorph/larva/new_xeno = spawn_hivenumber_larva(spawning_turf, hivenumber)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 64c851310823..4a5709ebce6b 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -401,7 +401,10 @@
/mob/living/launch_towards(datum/launch_metadata/LM)
if(src)
SEND_SIGNAL(src, COMSIG_MOB_MOVE_OR_LOOK, TRUE, dir, dir)
- if(!istype(LM) || !LM.target || !src || buckled)
+ if(!istype(LM) || !LM.target || !src)
+ return
+ if(buckled)
+ LM.invoke_end_throw_callbacks(src)
return
if(pulling)
stop_pulling() //being thrown breaks pulls.
diff --git a/code/modules/movement/launching/launching.dm b/code/modules/movement/launching/launching.dm
index e3eccf8dd1c2..1c2952599987 100644
--- a/code/modules/movement/launching/launching.dm
+++ b/code/modules/movement/launching/launching.dm
@@ -54,6 +54,16 @@
matching_procs += collision_callbacks[path]
return matching_procs
+/// Invoke end_throw_callbacks on this metadata.
+/// Takes argument of type /atom/movable
+/datum/launch_metadata/proc/invoke_end_throw_callbacks(atom/movable/movable_atom)
+ if(length(end_throw_callbacks))
+ for(var/datum/callback/callback as anything in end_throw_callbacks)
+ if(istype(callback, /datum/callback/dynamic))
+ callback.Invoke(movable_atom)
+ else
+ callback.Invoke()
+
/atom/movable/var/datum/launch_metadata/launch_metadata = null
//called when src is thrown into hit_atom
@@ -210,12 +220,7 @@
rebounding = FALSE
cur_speed = old_speed
remove_temp_pass_flags(pass_flags)
- if(length(LM.end_throw_callbacks))
- for(var/datum/callback/CB as anything in LM.end_throw_callbacks)
- if(istype(CB, /datum/callback/dynamic))
- CB.Invoke(src)
- else
- CB.Invoke()
+ LM.invoke_end_throw_callbacks(src)
QDEL_NULL(launch_metadata)
/atom/movable/proc/throw_random_direction(range, speed = 0, atom/thrower, spin, launch_type = NORMAL_LAUNCH, pass_flags = NO_FLAGS)
diff --git a/code/modules/projectiles/gun_attachables.dm b/code/modules/projectiles/gun_attachables.dm
index 0f3fde8f3c9b..e431dbab4dab 100644
--- a/code/modules/projectiles/gun_attachables.dm
+++ b/code/modules/projectiles/gun_attachables.dm
@@ -168,7 +168,8 @@ Defined in conflicts.dm of the #defines folder.
/obj/item/attachable/proc/Detach(mob/user, obj/item/weapon/gun/detaching_gub)
if(!istype(detaching_gub)) return //Guns only
- detaching_gub.on_detach(user)
+ if(user)
+ detaching_gub.on_detach(user, src)
if(flags_attach_features & ATTACH_ACTIVATION)
activate_attachment(detaching_gub, null, TRUE)
diff --git a/code/modules/projectiles/gun_helpers.dm b/code/modules/projectiles/gun_helpers.dm
index 8e73124a8b92..486e25315eef 100644
--- a/code/modules/projectiles/gun_helpers.dm
+++ b/code/modules/projectiles/gun_helpers.dm
@@ -395,7 +395,7 @@ DEFINES in setup.dm, referenced here.
playsound(user, 'sound/handling/attachment_add.ogg', 15, 1, 4)
return TRUE
-/obj/item/weapon/gun/proc/on_detach(obj/item/attachable/attachment)
+/obj/item/weapon/gun/proc/on_detach(mob/user, obj/item/attachable/attachment)
return
/obj/item/weapon/gun/proc/update_attachables() //Updates everything. You generally don't need to use this.
diff --git a/code/modules/tgs/v5/api.dm b/code/modules/tgs/v5/api.dm
index 25d49b3e3bdb..a5c064a8eaf1 100644
--- a/code/modules/tgs/v5/api.dm
+++ b/code/modules/tgs/v5/api.dm
@@ -8,8 +8,12 @@
var/reboot_mode = TGS_REBOOT_MODE_NORMAL
+ /// List of chat messages list()s that attempted to be sent during a topic call. To be bundled in the result of the call
var/list/intercepted_message_queue
+ /// List of chat messages list()s that attempted to be sent during a topic call. To be bundled in the result of the call
+ var/list/offline_message_queue
+
var/list/custom_commands
var/list/test_merges
@@ -194,17 +198,7 @@
var/datum/tgs_chat_channel/channel = I
ids += channel.id
- message2 = UpgradeDeprecatedChatMessage(message2)
-
- if (!length(channels))
- return
-
- var/list/data = message2._interop_serialize()
- data[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = ids
- if(intercepted_message_queue)
- intercepted_message_queue += list(data)
- else
- Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = data))
+ SendChatMessageRaw(message2, ids)
/datum/tgs_api/v5/ChatTargetedBroadcast(datum/tgs_message_content/message2, admin_only)
var/list/channels = list()
@@ -213,26 +207,42 @@
if (!channel.is_private_channel && ((channel.is_admin_channel && admin_only) || (!channel.is_admin_channel && !admin_only)))
channels += channel.id
+ SendChatMessageRaw(message2, channels)
+
+/datum/tgs_api/v5/ChatPrivateMessage(datum/tgs_message_content/message2, datum/tgs_chat_user/user)
+ SendChatMessageRaw(message2, list(user.channel.id))
+
+/datum/tgs_api/v5/proc/SendChatMessageRaw(datum/tgs_message_content/message2, list/channel_ids)
message2 = UpgradeDeprecatedChatMessage(message2)
- if (!length(channels))
+ if (!length(channel_ids))
return
var/list/data = message2._interop_serialize()
- data[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = channels
+ data[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = channel_ids
if(intercepted_message_queue)
intercepted_message_queue += list(data)
- else
- Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = data))
+ return
-/datum/tgs_api/v5/ChatPrivateMessage(datum/tgs_message_content/message2, datum/tgs_chat_user/user)
- message2 = UpgradeDeprecatedChatMessage(message2)
- var/list/data = message2._interop_serialize()
- data[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = list(user.channel.id)
- if(intercepted_message_queue)
- intercepted_message_queue += list(data)
+ if(offline_message_queue)
+ offline_message_queue += list(data)
+ return
+
+ if(detached)
+ offline_message_queue = list(data)
+
+ WaitForReattach(FALSE)
+
+ data = offline_message_queue
+ offline_message_queue = null
+
+ for(var/queued_message in data)
+ SendChatDataRaw(queued_message)
else
- Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = data))
+ SendChatDataRaw(data)
+
+/datum/tgs_api/v5/proc/SendChatDataRaw(list/data)
+ Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = data))
/datum/tgs_api/v5/ChatChannelInfo()
RequireInitialBridgeResponse()
diff --git a/html/changelogs/AutoChangeLog-pr-5440.yml b/html/changelogs/AutoChangeLog-pr-5440.yml
deleted file mode 100644
index f84625d30849..000000000000
--- a/html/changelogs/AutoChangeLog-pr-5440.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Drathek"
-delete-after: True
-changes:
- - bugfix: "Fix all hands on deck message not sending to those in cryopods"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-5443.yml b/html/changelogs/AutoChangeLog-pr-5443.yml
deleted file mode 100644
index 6a66c893b2ae..000000000000
--- a/html/changelogs/AutoChangeLog-pr-5443.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "TheGamerdk"
-delete-after: True
-changes:
- - bugfix: "Overwatch now works on Whiskey Outpost again, not that you will use it."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-5445.yml b/html/changelogs/AutoChangeLog-pr-5445.yml
deleted file mode 100644
index 6ad42c94ae06..000000000000
--- a/html/changelogs/AutoChangeLog-pr-5445.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Huffie56"
-delete-after: True
-changes:
- - rscadd: "Add the ability to build multi tile assembly from metal sheets."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-5449.yml b/html/changelogs/AutoChangeLog-pr-5449.yml
deleted file mode 100644
index 86fbc5f1b0db..000000000000
--- a/html/changelogs/AutoChangeLog-pr-5449.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Zonespace27"
-delete-after: True
-changes:
- - balance: "3 smartgun drums now spawn in the SG's equipment crate. Smartgun drums cannot be purchased from the SG vendor."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-5451.yml b/html/changelogs/AutoChangeLog-pr-5451.yml
deleted file mode 100644
index ff607b2d8cb6..000000000000
--- a/html/changelogs/AutoChangeLog-pr-5451.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "SabreML"
-delete-after: True
-changes:
- - bugfix: "Fixed dead marines being able to man and fire the M56D."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-5464.yml b/html/changelogs/AutoChangeLog-pr-5464.yml
new file mode 100644
index 000000000000..ec1b149fae9d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5464.yml
@@ -0,0 +1,4 @@
+author: "Birdtalon"
+delete-after: True
+changes:
+ - bugfix: "Fixed buckled mobs unable to move after being thrown by a xeno."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-5470.yml b/html/changelogs/AutoChangeLog-pr-5470.yml
new file mode 100644
index 000000000000..dbcad168f9a6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5470.yml
@@ -0,0 +1,4 @@
+author: "Drathek"
+delete-after: True
+changes:
+ - code_imp: "Cleaned up some oversights in attachment Detatch logic"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-5473.yml b/html/changelogs/AutoChangeLog-pr-5473.yml
new file mode 100644
index 000000000000..3c87f1c9bbfa
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5473.yml
@@ -0,0 +1,5 @@
+author: "SabreML"
+delete-after: True
+changes:
+ - rscadd: "Added a 'balloon alert' when toggling Crest Defense as a Defender."
+ - code_imp: "Made balloon alerts centre themselves on xeno sprites."
\ No newline at end of file
diff --git a/html/changelogs/archive/2024-01.yml b/html/changelogs/archive/2024-01.yml
index b16cf15ac751..86f76e98e37f 100644
--- a/html/changelogs/archive/2024-01.yml
+++ b/html/changelogs/archive/2024-01.yml
@@ -165,3 +165,22 @@
- bugfix: removed a light fixture being doubled on trijent
- maptweak: moved some trijent lights in marshals off windows
- maptweak: Alamayer PermaBrig Chairs face the right way
+2024-01-16:
+ Drathek:
+ - bugfix: Fix all hands on deck message not sending to those in cryopods
+ Huffie56:
+ - rscadd: Add the ability to build multi tile assembly from metal sheets.
+ ItsVyzo:
+ - balance: m56d loses burst fire
+ SabreML:
+ - bugfix: Fixed dead marines being able to man and fire the M56D.
+ TheGamerdk:
+ - bugfix: Overwatch now works on Whiskey Outpost again, not that you will use it.
+ Zonespace27:
+ - balance: 3 smartgun drums now spawn in the SG's equipment crate. Smartgun drums
+ cannot be purchased from the SG vendor.
+2024-01-17:
+ SabreML:
+ - bugfix: Fixed larvae sometimes spawning in space on Fiorina.
+ TheGamerdk:
+ - bugfix: The Kutjevo Refinery has been granted an additional SMES
diff --git a/maps/map_files/Kutjevo/Kutjevo.dmm b/maps/map_files/Kutjevo/Kutjevo.dmm
index d178ca9faddf..f93c14bee1cf 100644
--- a/maps/map_files/Kutjevo/Kutjevo.dmm
+++ b/maps/map_files/Kutjevo/Kutjevo.dmm
@@ -8549,6 +8549,12 @@
},
/turf/open/auto_turf/sand/layer0,
/area/kutjevo/interior/colony_north)
+"lBu" = (
+/obj/structure/machinery/power/terminal{
+ dir = 4
+ },
+/turf/open/floor/kutjevo/multi_tiles,
+/area/kutjevo/interior/power)
"lBP" = (
/obj/structure/window/framed/kutjevo/reinforced,
/obj/structure/machinery/door/poddoor/shutters/almayer{
@@ -25968,7 +25974,7 @@ uGd
fkP
vin
pBV
-hQj
+lBu
uBz
cvm
hQj
@@ -26135,7 +26141,7 @@ eyU
dyU
pyp
pyp
-hQj
+sNp
pyp
xjY
xjY