From a0c26a57683b5ebe2f93776297d0dfaa3a2dbef0 Mon Sep 17 00:00:00 2001
From: Vicacrov <49321394+Vicacrov@users.noreply.github.com>
Date: Wed, 13 Mar 2024 15:55:56 +0100
Subject: [PATCH 01/10] Adds an option to mute announcements while being an
observer (#5895)
# About the pull request
Adds a verb called `Hear/Silence Ghost Announcements`, accessible via
the Preferences tab and in Character Setup. It toggles the announcement
audio cue (queen screech, CIC beep, etc.) while the player is being an
**observer**. It does not affect in-character audio.
~~Slight issue with the PR right now is that it makes every current
player's announcements silent by default, it only turns on when creating
new prefs (if I did that correctly). I assume I would need @harryob for
updating our current players' prefs for this?~~
Edit: Updated the savefile with harry's guidance so it is turned on by
default for existing players as well.
# Explain why it's good for the game
Sometimes you tab out of the game for a few minutes, but god forbid you
are trying to watch YouTube or just chilling, because CIC and the Queen
are both spamming their ear-destroying announcements.
I assume this would be nice for staff too who are only online to listen
to ahelps.
# Testing Photographs and Procedure
1. Toggle the preference via the Preferences tab
2. Use the Report: verbs in the Admin tab
# Changelog
:cl:
add: Added an option to hear or silence announcement audio cues (queen
screech, CIC beep, etc.) while being an observer.
/:cl:
---------
Co-authored-by: Drathek <76988376+Drulikar@users.noreply.github.com>
Co-authored-by: SabreML <57483089+SabreML@users.noreply.github.com>
---
code/__DEFINES/__game.dm | 3 ++-
code/defines/procs/announcement.dm | 4 +++-
code/modules/client/preferences.dm | 4 ++++
code/modules/client/preferences_savefile.dm | 8 +++++++-
code/modules/client/preferences_toggles.dm | 8 ++++++++
5 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/code/__DEFINES/__game.dm b/code/__DEFINES/__game.dm
index a03701045768..6a9e9f1d4623 100644
--- a/code/__DEFINES/__game.dm
+++ b/code/__DEFINES/__game.dm
@@ -102,6 +102,7 @@
#define SOUND_ADMIN_MEME (1<<6)
#define SOUND_ADMIN_ATMOSPHERIC (1<<7)
#define SOUND_ARES_MESSAGE (1<<8)
+#define SOUND_OBSERVER_ANNOUNCEMENTS (1<<9)
//toggles_chat
#define CHAT_OOC (1<<0)
@@ -156,7 +157,7 @@
#define TOGGLES_LANGCHAT_DEFAULT (LANGCHAT_SEE_EMOTES)
-#define TOGGLES_SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_INTERNET|SOUND_ADMIN_MEME|SOUND_ADMIN_ATMOSPHERIC)
+#define TOGGLES_SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_INTERNET|SOUND_ADMIN_MEME|SOUND_ADMIN_ATMOSPHERIC|SOUND_OBSERVER_ANNOUNCEMENTS)
#define TOGGLES_FLASHING_DEFAULT (FLASH_ROUNDSTART|FLASH_ROUNDEND|FLASH_CORPSEREVIVE|FLASH_ADMINPM|FLASH_UNNEST)
diff --git a/code/defines/procs/announcement.dm b/code/defines/procs/announcement.dm
index 3eae6076f610..1963506431f3 100644
--- a/code/defines/procs/announcement.dm
+++ b/code/defines/procs/announcement.dm
@@ -90,7 +90,7 @@
//AI announcement that uses talking into comms
/proc/ai_announcement(message, sound_to_play = sound('sound/misc/interference.ogg'), logging = ARES_LOG_MAIN)
for(var/mob/M in (GLOB.human_mob_list + GLOB.dead_mob_list))
- if(isobserver(M) || ishuman(M) && is_mainship_level(M.z))
+ if((isobserver(M) && M.client?.prefs?.toggles_sound & SOUND_OBSERVER_ANNOUNCEMENTS) || ishuman(M) && is_mainship_level(M.z))
playsound_client(M.client, sound_to_play, M, vol = 45)
for(var/mob/living/silicon/decoy/ship_ai/AI in GLOB.ai_mob_list)
@@ -161,4 +161,6 @@
continue
to_chat_spaced(T, html = "[SPAN_ANNOUNCEMENT_HEADER(title)]
[SPAN_ANNOUNCEMENT_BODY(message)]", type = MESSAGE_TYPE_RADIO)
+ if(isobserver(T) && !(T.client?.prefs?.toggles_sound & SOUND_OBSERVER_ANNOUNCEMENTS))
+ return
playsound_client(T.client, sound_to_play, T, vol = 45)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 113d585e44ef..2fa98e03a52e 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -590,6 +590,7 @@ GLOBAL_LIST_INIT(bgstate_options, list(
dat += "tgui Window Mode: [(tgui_fancy) ? "Fancy (default)" : "Compatible (slower)"]
"
dat += "tgui Window Placement: [(tgui_lock) ? "Primary monitor" : "Free (default)"]
"
dat += "Play Admin Sounds: [(toggles_sound & SOUND_MIDI) ? "Yes" : "No"]
"
+ dat += "Play Announcement Sounds As Ghost: [(toggles_sound & SOUND_OBSERVER_ANNOUNCEMENTS) ? "Yes" : "No"]
"
dat += "Toggle Meme or Atmospheric Sounds: Toggle
"
dat += "Set Eye Blur Type: Set
"
dat += "Play Lobby Music: [(toggles_sound & SOUND_LOBBY) ? "Yes" : "No"]
"
@@ -1819,6 +1820,9 @@ GLOBAL_LIST_INIT(bgstate_options, list(
if(!(toggles_sound & SOUND_MIDI))
user?.client?.tgui_panel?.stop_music()
+ if("hear_observer_announcements")
+ toggles_sound ^= SOUND_OBSERVER_ANNOUNCEMENTS
+
if("lobby_music")
toggles_sound ^= SOUND_LOBBY
if(toggles_sound & SOUND_LOBBY)
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 8f3d10c102ce..5466fe105004 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -1,5 +1,5 @@
#define SAVEFILE_VERSION_MIN 8
-#define SAVEFILE_VERSION_MAX 21
+#define SAVEFILE_VERSION_MAX 22
//handles converting savefiles to new formats
//MAKE SURE YOU KEEP THIS UP TO DATE!
@@ -89,6 +89,12 @@
dual_wield_pref = DUAL_WIELD_FIRE
S["dual_wield_pref"] << dual_wield_pref
+ if(savefile_version < 22)
+ var/sound_toggles
+ S["toggles_sound"] >> sound_toggles
+ sound_toggles |= SOUND_OBSERVER_ANNOUNCEMENTS
+ S["toggles_sound"] << sound_toggles
+
savefile_version = SAVEFILE_VERSION_MAX
return 1
diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm
index d246a17bf5c0..32fd2225b339 100644
--- a/code/modules/client/preferences_toggles.dm
+++ b/code/modules/client/preferences_toggles.dm
@@ -25,6 +25,14 @@
prefs.save_preferences()
to_chat(src, SPAN_BOLDNOTICE("You will [(prefs.toggles_chat & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat."))
+/client/verb/toggle_observer_announcement_sounds()
+ set name = "Hear/Silence Ghost Announcements"
+ set category = "Preferences.Sound"
+ set desc = "Toggle hearing a notification of announcements while being an observer."
+ prefs.toggles_sound ^= SOUND_OBSERVER_ANNOUNCEMENTS
+ prefs.save_preferences()
+ to_chat(usr, SPAN_BOLDNOTICE("You will [(prefs.toggles_sound & SOUND_OBSERVER_ANNOUNCEMENTS) ? "now" : "no longer"] hear announcement sounds as an observer."))
+
/client/verb/toggletitlemusic()
set name = "Hear/Silence LobbyMusic"
set category = "Preferences.Sound"
From 514007f691e06a037e8893eff036db94a7abe336 Mon Sep 17 00:00:00 2001
From: cm13-github <128137806+cm13-github@users.noreply.github.com>
Date: Wed, 13 Mar 2024 15:02:08 +0000
Subject: [PATCH 02/10] Automatic changelog for PR #5895 [ci skip]
---
html/changelogs/AutoChangeLog-pr-5895.yml | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-5895.yml
diff --git a/html/changelogs/AutoChangeLog-pr-5895.yml b/html/changelogs/AutoChangeLog-pr-5895.yml
new file mode 100644
index 000000000000..a58a2b3596a6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5895.yml
@@ -0,0 +1,4 @@
+author: "Vicacrov"
+delete-after: True
+changes:
+ - rscadd: "Added an option to hear or silence announcement audio cues (queen screech, CIC beep, etc.) while being an observer."
\ No newline at end of file
From 5794a71d27cb529386c2c0ccb4fcdffa99861d35 Mon Sep 17 00:00:00 2001
From: Zonespace <41448081+Zonespace27@users.noreply.github.com>
Date: Wed, 13 Mar 2024 13:00:21 -0700
Subject: [PATCH 03/10] Tutorial documentation and proc update (#5921)
# About the pull request
Updates tutorial documentation.
Adds a proc, `mark_completed()`, that makes the tutorial count as
completed regardless of if `end_tutorial()` was called with `TRUE` or
`FALSE` as an argument. Necessary for
https://github.com/cmss13-devs/cmss13/pull/5909
---------
Co-authored-by: SabreML <57483089+SabreML@users.noreply.github.com>
---
code/datums/tutorial/_tutorial.dm | 8 +-
code/datums/tutorial/creating_a_tutorial.md | 128 +++++++++++---------
2 files changed, 79 insertions(+), 57 deletions(-)
diff --git a/code/datums/tutorial/_tutorial.dm b/code/datums/tutorial/_tutorial.dm
index f6e70e33cdd9..f228c051a77d 100644
--- a/code/datums/tutorial/_tutorial.dm
+++ b/code/datums/tutorial/_tutorial.dm
@@ -28,6 +28,8 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial)
var/parent_path = /datum/tutorial
/// A dictionary of "bind_name" : "keybind_button". The inverse of `key_bindings` on a client's prefs
var/list/player_bind_dict = list()
+ /// If the tutorial has been completed. This doesn't need to be modified if you call end_tutorial() with a param of TRUE
+ var/completion_marked = FALSE
/datum/tutorial/Destroy(force, ...)
GLOB.ongoing_tutorials -= src
@@ -83,7 +85,7 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial)
if(tutorial_mob)
remove_action(tutorial_mob, /datum/action/tutorial_end) // Just in case to make sure the client can't try and leave the tutorial while it's mid-cleanup
- if(tutorial_mob.client?.prefs && completed)
+ if(tutorial_mob.client?.prefs && (completed || completion_marked))
tutorial_mob.client.prefs.completed_tutorials |= tutorial_id
tutorial_mob.client.prefs.save_character()
var/mob/new_player/new_player = new
@@ -210,6 +212,10 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial)
return player_bind_dict[action_name][1]
+/// When called, will make anything that ends the tutorial mark it as completed. Does not need to be called if end_tutorial(TRUE) is called instead
+/datum/tutorial/proc/mark_completed()
+ completion_marked = TRUE
+
/datum/action/tutorial_end
name = "Stop Tutorial"
action_icon_state = "hologram_exit"
diff --git a/code/datums/tutorial/creating_a_tutorial.md b/code/datums/tutorial/creating_a_tutorial.md
index 96a7cb886820..4ed1a379f348 100644
--- a/code/datums/tutorial/creating_a_tutorial.md
+++ b/code/datums/tutorial/creating_a_tutorial.md
@@ -1,17 +1,15 @@
# Tutorial Creation
-[ToC]
-
## Step 1: Identifying the Goal
Your first objective when making a tutorial should be to have a clear and concise vision of what you want the tutorial to convey to the user. People absorb information better in smaller chunks, so you should ideally keep a tutorial to one section of information at a time.
For example, if you are making a tutorial for new CM players, it should be split into multiple parts like:
-- Basics
-- Medical
-- Weaponry
-- Requisitions/Communication
+- Basics
+- Medical
+- Weaponry
+- Requisitions/Communication
## Step 2: Coding
@@ -20,47 +18,65 @@ For an example of the current code standards for tutorials, see [this](https://g
The API for tutorials is designed to be very simple, so I'll go over all the base `/datum/tutorial` procs and some vars here:
### Variables
-- `name`
- - This is the player-facing name of the tutorial.
-- `tutorial_id`
- - This is the back-end ID of the tutorial, used for save files. Try not to change a tutorial's ID after it's on the live server.
-- `category`
- - This is what category the tutorial should be under. Use the `TUTORIAL_CATEGORY_XXXX` macros.
-- `tutorial_template`
- - This is what type the map template of the tutorial should be. The default space is 12x12; ideally make it so it fits the given scale of the tutorial with some wiggle room for the player to move around.
-- `parent_path`
- - This is the top-most parent `/datum/tutorial` path, used to exclude abstract parents from the tutorial menu. For example, `/datum/tutorial/marine/basic` would have a `parent_path` of `/datum/tutorial/marine`, since that path is the top-most abstract path.
+
+- `name`
+ - This is the player-facing name of the tutorial.
+- `tutorial_id`
+ - This is the back-end ID of the tutorial, used for save files. Try not to change a tutorial's ID after it's on the live server.
+- `category`
+ - This is what category the tutorial should be under. Use the `TUTORIAL_CATEGORY_XXXX` macros.
+- `tutorial_template`
+ - This is what type the map template of the tutorial should be. The default space is 12x12; ideally make it so it fits the given scale of the tutorial with some wiggle room for the player to move around.
+- `parent_path`
+ - This is the top-most parent `/datum/tutorial` path, used to exclude abstract parents from the tutorial menu. For example, `/datum/tutorial/marine/basic` would have a `parent_path` of `/datum/tutorial/marine`, since that path is the top-most abstract path.
+- `completion_marked`
+ - If this is `TRUE`, the tutorial will be marked as completed if ended in any way. You can modify this with `mark_completed()` but is not necessary if `end_tutorial(TRUE)` is called.
### Procs
-- `start_tutorial(mob/starting_mob)`
- - This proc starts the tutorial, setting up the map template and player. This should be overridden with a parent call before any overridden code.
-- `end_tutorial(completed = FALSE)`
- - This proc ends the tutorial, sending the player back to the lobby and deleting the tutorial itself. A parent call on any subtypes should be at the end of the overridden segment. If `completed` is `TRUE`, then the tutorial will save as a completed one for the user.
-- `add_highlight(atom/target, color = "#d19a02")`
- - This proc adds a highlight filter around an atom, by default this color. Successive calls of highlight on the same atom will override the last.
-- `remove_highlight(atom/target)`
- - This proc removes the tutorial highlight from a target.
-- `add_to_tracking_atoms(atom/reference)`
- - This proc will add a reference to the tutorial's tracked atom dictionary. For what a tracked atom is, see Step 2.1.
-- `remove_from_tracking_atoms(atom/reference)`
- - This proc will remove a reference from the tutorial's tracked atom dictionary. For what a tracked atom is, see Step 2.1.
-- `message_to_player(message)`
- - This proc is the ideal way to communicate to a player. It is visually similar to overwatch messages or weather alerts, but appears and disappears much faster. The messages sent should be consise, but can have a degree of dialogue to them.
-- `update_objective(message)`
- - This proc is used to update the player's objective in their status panel. This should be only what is required and how to do it without any dialogue or extra text.
-- `init_mob()`
- - This proc is used to initialize the mob and set them up correctly.
-- `init_map()`
- - This proc does nothing by default, but can be overriden to spawn any atoms necessary for the tutorial from the very start.
-- `tutorial_end_in(time = 5 SECONDS, completed = TRUE)`
- - This proc will end the tutorial in the given time, defaulting to 5 seconds. Once the proc is called, the player will be booted back to the menu screen after the time is up. Will mark the tutorial as completed if `completed` is `TRUE`
-- `loc_from_corner(offset_x = 0, offset_y = 0)`
- - This proc will return a turf offset from the bottom left corner of the tutorial zone. Keep in mind, the bottom left corner is NOT on a wall, it is on the first floor on the bottom left corner. `offset_x` and `offset_y` are used to offset what turf you want to get, and should never be negative.
+
+- `start_tutorial(mob/starting_mob)`
+ - This proc starts the tutorial, setting up the map template and player. This should be overridden with a parent call before any overridden code.
+- `end_tutorial(completed = FALSE)`
+ - This proc ends the tutorial, sending the player back to the lobby and deleting the tutorial itself. A parent call on any subtypes should be at the end of the overridden segment. If `completed` is `TRUE`, then the tutorial will save as a completed one for the user. If `mark_completed()` was called previously, the tutorial will count as completed regardless of if this is called with an argument of `TRUE` or `FALSE`.
+- `add_highlight(atom/target, color = "#d19a02")`
+ - This proc adds a highlight filter around an atom, by default this color. Successive calls of highlight on the same atom will override the last.
+- `remove_highlight(atom/target)`
+ - This proc removes the tutorial highlight from a target.
+- `add_to_tracking_atoms(atom/reference)`
+ - This proc will add a reference to the tutorial's tracked atom dictionary. For what a tracked atom is, see Step 2.1.
+- `remove_from_tracking_atoms(atom/reference)`
+ - This proc will remove a reference from the tutorial's tracked atom dictionary. For what a tracked atom is, see Step 2.1.
+- `message_to_player(message)`
+ - This proc is the ideal way to communicate to a player. It is visually similar to overwatch messages or weather alerts, but appears and disappears much faster. The messages sent should be consise, but can have a degree of dialogue to them.
+- `update_objective(message)`
+ - This proc is used to update the player's objective in their status panel. This should be only what is required and how to do it without any dialogue or extra text.
+- `init_mob()`
+ - This proc is used to initialize the mob and set them up correctly.
+- `init_map()`
+ - This proc does nothing by default, but can be overriden to spawn any atoms necessary for the tutorial from the very start.
+- `tutorial_end_in(time = 5 SECONDS, completed = TRUE)`
+ - This proc will end the tutorial in the given time, defaulting to 5 seconds. Once the proc is called, the player will be booted back to the menu screen after the time is up. Will mark the tutorial as completed if `completed` is `TRUE`
+- `loc_from_corner(offset_x = 0, offset_y = 0)`
+ - This proc will return a turf offset from the bottom left corner of the tutorial zone. Keep in mind, the bottom left corner is NOT on a wall, it is on the first floor on the bottom left corner. `offset_x` and `offset_y` are used to offset what turf you want to get, and should never be negative.
+- `on_ghost(datum/source, mob/dead/observer/ghost)`
+ - This proc is used to properly end and clean up the tutorial should a player ghost out. You shouldn't need to override or modify this when making a tutorial.
+- `signal_end_tutorial(datum/source)`
+ - This proc is used to call `end_tutorial()` via signals. If something (e.g. a player dying) should send a signal that ends the tutorial, have the signal call this proc.
+- `on_logout(datum/source)`
+ - This proc is called when a player logs out, disconnecting their client from the server. As with `on_ghost()` and similar procs, it cleans up and ends the tutorial.
+- `generate_binds()`
+ - This proc generates a dictionary of the player's keybinds, in the form of {"action_name" : "key_to_press"}. This is used for the `retrieve_bind()` proc to be able to tell the user what buttons to press.
+- `retrieve_bind(action_name)`
+ - This proc will be one you'll get a fair amount of use from. Whenever you tell the user to do something like "drop an item", you should tell them what button to press by calling `retrieve_bind("drop_item")` in the string telling them to drop an item.
+- `mark_completed()`
+ - This proc can be used as an alternative to calling `end_tutorial(TRUE)`. Calling this proc means any method of exiting the tutorial (ghosting, dying, pressing the exit button) will mark the tutorial as completed.
## Step 2.1: Tracking Atoms
+
Naturally, you will need to keep track of certain objects or mobs for signal purposes, so the tracking system exists to fill that purpose. When you add a reference to the tracking atom list with `add_to_tracking_atoms()`, it gets put into a dictionary of `{path : reference}`. Because of this limitation, you should not track more than 1 object of the same type. To get a tracked atom, use of the `TUTORIAL_ATOM_FROM_TRACKING(path, varname)` macro is recommended. `path` should be replaced with the precise typepath of the tracked atom, and `varname` should be replaced with the variable name you wish to use. If an object is going to be deleted, remove it with `remove_from_tracking_atoms()` first.
## Step 2.2: Scripting Format
+
Any proc whose main purpose is to advance the tutorial will be hereon referred to as a "script proc", as part of the entire "script". In the vast majority of cases, a script proc should hand off to the next using signals. Here is an example from `basic_marine.dm`:
```javascript
@@ -69,8 +85,8 @@ Any proc whose main purpose is to advance the tutorial will be hereon referred t
UnregisterSignal(tracking_atoms[/obj/structure/machinery/cryopod/tutorial], COMSIG_CRYOPOD_GO_OUT)
message_to_player("Good. You may notice the yellow \"food\" icon on the right side of your screen. Proceed to the outlined Food Vendor and vend the USCM Protein Bar.")
- update_objective("Vend a USCM Protein Bar from the outlined ColMarTech Food Vendor.")
- TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cm_vending/sorted/marine_food/tutorial, food_vendor)
+ update_objective("Vend a USCM Protein Bar from the outlined ColMarTech Food Vendor.")
+ TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cm_vending/sorted/marine_food/tutorial, food_vendor)
add_highlight(food_vendor)
food_vendor.req_access = list()
RegisterSignal(food_vendor, COMSIG_VENDOR_SUCCESSFUL_VEND, PROC_REF(on_food_vend))
@@ -78,19 +94,19 @@ Any proc whose main purpose is to advance the tutorial will be hereon referred t
```
Line-by-line:
- - `SIGNAL_HANDLER` is necessary as this proc was called via signal.
- - Here we are unregistering the signal we registered in the previous proc to call this one, which in this case was waiting for the player to leave the tracked cryopod.
- - Now, we tell the user the next step in the script, which is sent to their screen.
- - Here we update the player's status panel with similar info to the above line, but far more condensed.
- - Since we need to access the food vendor, we use the `TUTORIAL_ATOM_FROM_TRACKING()` macro to get a ref to it.
- - We add a yellow outline to the food vendor to make it more clear what is wanted of the player
- - The tutorial food vendors are locked to `ACCESS_TUTORIAL_LOCKED` by default, so here we remove that access requirement
- - And finally, we register a signal for the next script proc, waiting for the user to vend something from the food vendor.
-
+- `SIGNAL_HANDLER` is necessary as this proc was called via signal.
+- Here we are unregistering the signal we registered in the previous proc to call this one, which inthis case was waiting for the player to leave the tracked cryopod.
+- Now, we tell the user the next step in the script, which is sent to their screen.
+- Here we update the player's status panel with similar info to the above line, but far morecondensed.
+- Since we need to access the food vendor, we use the `TUTORIAL_ATOM_FROM_TRACKING()` macro to get aref to it.
+- We add a yellow outline to the food vendor to make it more clear what is wanted of the player
+- The tutorial food vendors are locked to `ACCESS_TUTORIAL_LOCKED` by default, so here we remove thataccess requirement
+- And finally, we register a signal for the next script proc, waiting for the user to vend something from the food vendor.
## Step 2.3: Quirks & Tips
-- Generally speaking, you will want to create `/tutorial` subtypes of anything you add in the tutorial, should it need any special functions or similar.
-- Restrict access from players as much as possible. As seen in the example above, restricting access to vendors and similar machines is recommended to prevent sequence breaking. Additionally, avoid adding anything that detracts from the tutorial itself.
-- Attempt to avoid softlocks when possible. If someone could reasonably do something (e.g. firing every bullet they have at a ranged target and missing, now unable to kill them and progress) that could softlock them, then there should be a fallback of some sort. However, accomodations don't need to be made for people who purposefully cause a softlock; there's a "stop tutorial" button for a reason.
-- When calling `message_to_player()` or `update_objective()`, **bold** the names of objects, items, and keybinds.
-- Attempt to bind as many scripting signals to the `tutorial_mob` as possible. The nature of SS13 means something as sequence-heavy as this will always be fragile, so keeping the fragility we can affect to a minimum is imperative.
+
+- Generally speaking, you will want to create `/tutorial` subtypes of anything you add in the tutorial, should it need any special functions or similar.
+- Restrict access from players as much as possible. As seen in the example above, restricting access to vendors and similar machines is recommended to prevent sequence breaking. Additionally, avoid adding anything that detracts from the tutorial itself.
+- Attempt to avoid softlocks when possible. If someone could reasonably do something (e.g. firing every bullet they have at a ranged target and missing, now unable to kill them and progress) that could softlock them, then there should be a fallback of some sort. However, accomodations don't need to be made for people who purposefully cause a softlock; there's a "stop tutorial" button for a reason.
+- When calling `message_to_player()` or `update_objective()`, **bold** the names of objects, items, and keybinds.
+- Attempt to bind as many scripting signals to the `tutorial_mob` as possible. The nature of SS13 means something as sequence-heavy as this will always be fragile, so keeping the fragility we can affect to a minimum is imperative.
From 9a076b3fa264b107c4f38ea14f8e883950c2a0b4 Mon Sep 17 00:00:00 2001
From: Changelogs
Date: Thu, 14 Mar 2024 01:07:04 +0000
Subject: [PATCH 04/10] Automatic changelog compile [ci skip]
---
html/changelogs/AutoChangeLog-pr-5838.yml | 7 -------
html/changelogs/AutoChangeLog-pr-5895.yml | 4 ----
html/changelogs/archive/2024-03.yml | 11 +++++++++++
3 files changed, 11 insertions(+), 11 deletions(-)
delete mode 100644 html/changelogs/AutoChangeLog-pr-5838.yml
delete mode 100644 html/changelogs/AutoChangeLog-pr-5895.yml
diff --git a/html/changelogs/AutoChangeLog-pr-5838.yml b/html/changelogs/AutoChangeLog-pr-5838.yml
deleted file mode 100644
index d180f50f7635..000000000000
--- a/html/changelogs/AutoChangeLog-pr-5838.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "nauticall"
-delete-after: True
-changes:
- - imageadd: "Resprites first aid kits, coffins, material stacks, mortar shells, and chemistry items. Chemistry sprites ported from Baystation / Aurora."
- - bugfix: "Recolors several reagent sprites to be more in-line with their established colors, such as on autoinjectors."
- - bugfix: "Fixed invisible cloth tables."
- - bugfix: "Fixed wrong shading on the large floodlight."
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-5895.yml b/html/changelogs/AutoChangeLog-pr-5895.yml
deleted file mode 100644
index a58a2b3596a6..000000000000
--- a/html/changelogs/AutoChangeLog-pr-5895.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Vicacrov"
-delete-after: True
-changes:
- - rscadd: "Added an option to hear or silence announcement audio cues (queen screech, CIC beep, etc.) while being an observer."
\ No newline at end of file
diff --git a/html/changelogs/archive/2024-03.yml b/html/changelogs/archive/2024-03.yml
index 89c57884d3fd..4962062da515 100644
--- a/html/changelogs/archive/2024-03.yml
+++ b/html/changelogs/archive/2024-03.yml
@@ -149,3 +149,14 @@
- bugfix: Doctors calling themselves surgeons now properly get playtime medals.
- bugfix: Playtime medals now use assignments instead of backend paygrade codes
(e.g. "Awarded to Squad Leader John Doe" instead of "Awarded to ME5 John Doe").
+2024-03-14:
+ Vicacrov:
+ - rscadd: Added an option to hear or silence announcement audio cues (queen screech,
+ CIC beep, etc.) while being an observer.
+ nauticall:
+ - imageadd: Resprites first aid kits, coffins, material stacks, mortar shells, and
+ chemistry items. Chemistry sprites ported from Baystation / Aurora.
+ - bugfix: Recolors several reagent sprites to be more in-line with their established
+ colors, such as on autoinjectors.
+ - bugfix: Fixed invisible cloth tables.
+ - bugfix: Fixed wrong shading on the large floodlight.
From 8c6650d5d0e2752d8d3e3299c733dcd6e15a9ecb Mon Sep 17 00:00:00 2001
From: Julian56 <117036822+Huffie56@users.noreply.github.com>
Date: Thu, 14 Mar 2024 08:23:23 +0100
Subject: [PATCH 05/10] Balance : adding M44 Marksman Speed Loader and SU-6
Smartpistol Magazine to marine squads vendors. (#5908)
# About the pull request
# Explain why it's good for the game
Mainly for consistency and because those ammo are available for free in
any prep.
allowing marine to buy some if vendor is empty seem fair to me.
# Testing Photographs and Procedure
Screenshots & Videos
Put screenshots and videos here with an empty line between the
screenshots and the `` tags.
# Changelog
:cl:
balance: adding M44 Marksman Speed Loader and SU-6 Smartpistol Magazine
in vendor of (medic,comtech, SL) at a cost of 6 each.
balance: adding M44 Marksman Speed Loader and SU-6 Smartpistol Magazine
in vendor of (rifleman, TL, IO) at a cost of 10 each.
balance: adding VP78 case and SU-6 case in vendor of IO at a cost of 15
each.
/:cl:
---------
Co-authored-by: Julien
---
.../machinery/vending/vendor_types/intelligence_officer.dm | 6 ++++++
.../vending/vendor_types/squad_prep/squad_engineer.dm | 2 ++
.../vending/vendor_types/squad_prep/squad_leader.dm | 2 ++
.../vending/vendor_types/squad_prep/squad_medic.dm | 2 ++
.../vending/vendor_types/squad_prep/squad_rifleman.dm | 2 ++
.../machinery/vending/vendor_types/squad_prep/squad_tl.dm | 2 ++
6 files changed, 16 insertions(+)
diff --git a/code/game/machinery/vending/vendor_types/intelligence_officer.dm b/code/game/machinery/vending/vendor_types/intelligence_officer.dm
index 954c3438a4c9..9baa685032de 100644
--- a/code/game/machinery/vending/vendor_types/intelligence_officer.dm
+++ b/code/game/machinery/vending/vendor_types/intelligence_officer.dm
@@ -18,9 +18,15 @@ GLOBAL_LIST_INIT(cm_vending_gear_intelligence_officer, list(
list("SIDEARM AMMUNITION", 0, null, null, null),
list("M44 Heavy Speed Loader (.44)", 10, /obj/item/ammo_magazine/revolver/heavy, null, VENDOR_ITEM_REGULAR),
+ list("M44 Marksman Speed Loader (.44)", 10, /obj/item/ammo_magazine/revolver/marksman, null, VENDOR_ITEM_REGULAR),
list("M4A3 HP Magazine", 5, /obj/item/ammo_magazine/pistol/hp, null, VENDOR_ITEM_REGULAR),
list("M4A3 AP Magazine", 5, /obj/item/ammo_magazine/pistol/ap, null, VENDOR_ITEM_REGULAR),
list("VP78 Magazine", 5, /obj/item/ammo_magazine/pistol/vp78, null, VENDOR_ITEM_REGULAR),
+ list("SU-6 Smartpistol Magazine (.45)", 10, /obj/item/ammo_magazine/pistol/smart, null, VENDOR_ITEM_REGULAR),
+
+ list("RESTRICTED FIREARMS", 0, null, null, null),
+ list("VP78 Pistol", 15, /obj/item/storage/box/guncase/vp78, null, VENDOR_ITEM_REGULAR),
+ list("SU-6 Smart Pistol", 15, /obj/item/storage/box/guncase/smartpistol, null, VENDOR_ITEM_REGULAR),
list("POUCHES", 0, null, null, null),
list("Large Magazine Pouch", 10, /obj/item/storage/pouch/magazine/large, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm
index 95864404f4e8..998b17504a44 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm
@@ -45,9 +45,11 @@ GLOBAL_LIST_INIT(cm_vending_gear_engi, list(
list("SIDEARM AMMUNITION", 0, null, null, null),
list("M44 Heavy Speed Loader (.44)", 6, /obj/item/ammo_magazine/revolver/heavy, null, VENDOR_ITEM_REGULAR),
+ list("M44 Marksman Speed Loader (.44)", 6, /obj/item/ammo_magazine/revolver/marksman, null, VENDOR_ITEM_REGULAR),
list("M4A3 HP Magazine", 3, /obj/item/ammo_magazine/pistol/hp, null, VENDOR_ITEM_REGULAR),
list("M4A3 AP Magazine", 3, /obj/item/ammo_magazine/pistol/ap, null, VENDOR_ITEM_REGULAR),
list("VP78 Magazine", 3, /obj/item/ammo_magazine/pistol/vp78, null, VENDOR_ITEM_REGULAR),
+ list("SU-6 Smartpistol Magazine (.45)", 6, /obj/item/ammo_magazine/pistol/smart, null, VENDOR_ITEM_REGULAR),
list("ARMORS", 0, null, null, null),
list("M3 B12 Pattern Marine Armor", 24, /obj/item/clothing/suit/storage/marine/medium/leader, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm
index 0039d5b03250..17d3419ac2f8 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm
@@ -88,9 +88,11 @@ GLOBAL_LIST_INIT(cm_vending_gear_leader, list(
list("SIDEARM AMMUNITION", 0, null, null, null),
list("M44 Heavy Speed Loader (.44)", 6, /obj/item/ammo_magazine/revolver/heavy, null, VENDOR_ITEM_REGULAR),
+ list("M44 Marksman Speed Loader (.44)", 6, /obj/item/ammo_magazine/revolver/marksman, null, VENDOR_ITEM_REGULAR),
list("M4A3 HP Magazine", 3, /obj/item/ammo_magazine/pistol/hp, null, VENDOR_ITEM_REGULAR),
list("M4A3 AP Magazine", 3, /obj/item/ammo_magazine/pistol/ap, null, VENDOR_ITEM_REGULAR),
list("VP78 Magazine", 3, /obj/item/ammo_magazine/pistol/vp78, null, VENDOR_ITEM_REGULAR),
+ list("SU-6 Smartpistol Magazine (.45)", 6, /obj/item/ammo_magazine/pistol/smart, null, VENDOR_ITEM_REGULAR),
list("SPECIAL AMMUNITION", 0, null, null, null),
list("M240 Incinerator Tank (Napthal)", 3, /obj/item/ammo_magazine/flamer_tank, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm
index b29b528ded13..b1961ae9e75b 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm
@@ -67,9 +67,11 @@ GLOBAL_LIST_INIT(cm_vending_gear_medic, list(
list("SIDEARM AMMUNITION", 0, null, null, null),
list("M44 Heavy Speed Loader (.44)", 6, /obj/item/ammo_magazine/revolver/heavy, null, VENDOR_ITEM_REGULAR),
+ list("M44 Marksman Speed Loader (.44)", 6, /obj/item/ammo_magazine/revolver/marksman, null, VENDOR_ITEM_REGULAR),
list("M4A3 HP Magazine", 3, /obj/item/ammo_magazine/pistol/hp, null, VENDOR_ITEM_REGULAR),
list("M4A3 AP Magazine", 3, /obj/item/ammo_magazine/pistol/ap, null, VENDOR_ITEM_REGULAR),
list("VP78 Magazine", 3, /obj/item/ammo_magazine/pistol/vp78, null, VENDOR_ITEM_REGULAR),
+ list("SU-6 Smartpistol Magazine (.45)", 6, /obj/item/ammo_magazine/pistol/smart, null, VENDOR_ITEM_REGULAR),
list("ARMORS", 0, null, null, null),
list("M3 B12 Pattern Marine Armor", 24, /obj/item/clothing/suit/storage/marine/medium/leader, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm
index 0b980fc31960..65066731070d 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm
@@ -76,9 +76,11 @@ GLOBAL_LIST_INIT(cm_vending_clothing_marine, list(
list("SIDEARM AMMUNITION", 0, null, null, null),
list("M44 Heavy Speed Loader (.44)", 10, /obj/item/ammo_magazine/revolver/heavy, null, VENDOR_ITEM_REGULAR),
+ list("M44 Marksman Speed Loader (.44)", 10, /obj/item/ammo_magazine/revolver/marksman, null, VENDOR_ITEM_REGULAR),
list("M4A3 HP Magazine", 5, /obj/item/ammo_magazine/pistol/hp, null, VENDOR_ITEM_REGULAR),
list("M4A3 AP Magazine", 5, /obj/item/ammo_magazine/pistol/ap, null, VENDOR_ITEM_REGULAR),
list("VP78 Magazine", 5, /obj/item/ammo_magazine/pistol/vp78, null, VENDOR_ITEM_REGULAR),
+ list("SU-6 Smartpistol Magazine (.45)", 10, /obj/item/ammo_magazine/pistol/smart, null, VENDOR_ITEM_REGULAR),
list("ARMORS", 0, null, null, null),
list("M3 B12 Pattern Marine Armor", 30, /obj/item/clothing/suit/storage/marine/medium/leader, null, VENDOR_ITEM_REGULAR),
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm
index a013ddb15212..c37dd98ed263 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm
@@ -22,9 +22,11 @@ GLOBAL_LIST_INIT(cm_vending_gear_tl, list(
list("SIDEARM AMMUNITION", 0, null, null, null),
list("M44 Heavy Speed Loader (.44)", 10, /obj/item/ammo_magazine/revolver/heavy, null, VENDOR_ITEM_REGULAR),
+ list("M44 Marksman Speed Loader (.44)", 10, /obj/item/ammo_magazine/revolver/marksman, null, VENDOR_ITEM_REGULAR),
list("M4A3 HP Magazine", 5, /obj/item/ammo_magazine/pistol/hp, null, VENDOR_ITEM_REGULAR),
list("M4A3 AP Magazine", 5, /obj/item/ammo_magazine/pistol/ap, null, VENDOR_ITEM_REGULAR),
list("VP78 Magazine", 5, /obj/item/ammo_magazine/pistol/vp78, null, VENDOR_ITEM_REGULAR),
+ list("SU-6 Smartpistol Magazine (.45)", 10, /obj/item/ammo_magazine/pistol/smart, null, VENDOR_ITEM_REGULAR),
list("RESTRICTED FIREARMS", 0, null, null, null),
list("VP78 Pistol", 10, /obj/item/storage/box/guncase/vp78, null, VENDOR_ITEM_REGULAR),
From e7629fcc28164d220db9b15e8ec7b1eb70344eb5 Mon Sep 17 00:00:00 2001
From: cm13-github <128137806+cm13-github@users.noreply.github.com>
Date: Thu, 14 Mar 2024 07:31:25 +0000
Subject: [PATCH 06/10] Automatic changelog for PR #5908 [ci skip]
---
html/changelogs/AutoChangeLog-pr-5908.yml | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-5908.yml
diff --git a/html/changelogs/AutoChangeLog-pr-5908.yml b/html/changelogs/AutoChangeLog-pr-5908.yml
new file mode 100644
index 000000000000..5b62ea4ebe26
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5908.yml
@@ -0,0 +1,6 @@
+author: "Huffie56"
+delete-after: True
+changes:
+ - balance: "adding M44 Marksman Speed Loader and SU-6 Smartpistol Magazine in vendor of (medic,comtech, SL) at a cost of 6 each."
+ - balance: "adding M44 Marksman Speed Loader and SU-6 Smartpistol Magazine in vendor of (rifleman, TL, IO) at a cost of 10 each."
+ - balance: "adding VP78 case and SU-6 case in vendor of IO at a cost of 15 each."
\ No newline at end of file
From f4bbd814d3147bf432ba04de99e4fb9b02561213 Mon Sep 17 00:00:00 2001
From: Julian56 <117036822+Huffie56@users.noreply.github.com>
Date: Thu, 14 Mar 2024 08:31:06 +0100
Subject: [PATCH 07/10] Changes to SG vendor add the ability to buy more
sidearm ammo type and a smartgun battery. (#5913)
# About the pull request
# Explain why it's good for the game
# Testing Photographs and Procedure
Screenshots & Videos
Put screenshots and videos here with an empty line between the
screenshots and the `` tags.
# Changelog
:cl:
balance: adding M44 Marksman Speed Loader and SU-6 Smartpistol Magazine
in SG vendor for 10 point each.
balance: adding the ability for to buy smartgun DV9 battery for 15
points in SG vendor.
/:cl:
---------
Co-authored-by: Julien
Co-authored-by: Drathek <76988376+Drulikar@users.noreply.github.com>
---
.../vending/vendor_types/squad_prep/squad_smartgunner.dm | 3 +++
1 file changed, 3 insertions(+)
diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm
index 8c64e48f0f84..60afed8b984d 100644
--- a/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm
+++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm
@@ -22,9 +22,11 @@ GLOBAL_LIST_INIT(cm_vending_gear_smartgun, list(
list("SIDEARM AMMUNITION", 0, null, null, null),
list("M44 Heavy Speed Loader (.44)", 10, /obj/item/ammo_magazine/revolver/heavy, null, VENDOR_ITEM_REGULAR),
+ list("M44 Marksman Speed Loader (.44)", 10, /obj/item/ammo_magazine/revolver/marksman, null, VENDOR_ITEM_REGULAR),
list("M4A3 HP Magazine", 5, /obj/item/ammo_magazine/pistol/hp, null, VENDOR_ITEM_REGULAR),
list("M4A3 AP Magazine", 5, /obj/item/ammo_magazine/pistol/ap, null, VENDOR_ITEM_REGULAR),
list("VP78 Magazine", 5, /obj/item/ammo_magazine/pistol/vp78, null, VENDOR_ITEM_REGULAR),
+ list("SU-6 Smartpistol Magazine (.45)", 10, /obj/item/ammo_magazine/pistol/smart, null, VENDOR_ITEM_REGULAR),
list("RESTRICTED FIREARMS", 0, null, null, null),
list("VP78 Pistol", 15, /obj/item/storage/box/guncase/vp78, null, VENDOR_ITEM_REGULAR),
@@ -40,6 +42,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_smartgun, list(
list("Whistle", 5, /obj/item/device/whistle, null, VENDOR_ITEM_REGULAR),
list("Roller Bed", 5, /obj/item/roller, null, VENDOR_ITEM_REGULAR),
list("Fulton Device Stack", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR),
+ list("Smartgun DV9 Battery", 15, /obj/item/smartgun_battery, null, VENDOR_ITEM_REGULAR),
list("BINOCULARS", 0, null, null, null),
list("Binoculars", 5, /obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR),
From 80fcf5ca09f4cd9362c9ae2b3e19930f05559fac Mon Sep 17 00:00:00 2001
From: cm13-github <128137806+cm13-github@users.noreply.github.com>
Date: Thu, 14 Mar 2024 07:41:43 +0000
Subject: [PATCH 08/10] Automatic changelog for PR #5913 [ci skip]
---
html/changelogs/AutoChangeLog-pr-5913.yml | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-5913.yml
diff --git a/html/changelogs/AutoChangeLog-pr-5913.yml b/html/changelogs/AutoChangeLog-pr-5913.yml
new file mode 100644
index 000000000000..644ce42a8b5f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5913.yml
@@ -0,0 +1,5 @@
+author: "Huffie56"
+delete-after: True
+changes:
+ - balance: "adding M44 Marksman Speed Loader and SU-6 Smartpistol Magazine in SG vendor for 10 point each."
+ - balance: "adding the ability for to buy smartgun DV9 battery for 15 points in SG vendor."
\ No newline at end of file
From ec7b8cf4e93263967c6a034ee772125304ac8d02 Mon Sep 17 00:00:00 2001
From: Segrain
Date: Thu, 14 Mar 2024 15:45:16 +0400
Subject: [PATCH 09/10] Middleclick buckling. (#5899)
# About the pull request
Drag self onto table = climb table.
Middleclick table = climb table.
Drag self onto chair = buckle to chair.
Middleclick chair = ?
# Explain why it's good for the game
Is QoL.
# Changelog
:cl:
qol: Middleclicking beds/chairs/etc is now a shortcut for buckling to
them.
/:cl:
---
code/_onclick/other_mobs.dm | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index 0bfa0a759287..8176f9e5247c 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -11,7 +11,10 @@
if (mods["middle"])
if (isStructure(A) && get_dist(src, A) <= 1)
var/obj/structure/S = A
- S.do_climb(src, mods)
+ if(S.climbable)
+ S.do_climb(src, mods)
+ else if(S.can_buckle)
+ S.buckle_mob(src, src)
return TRUE
else if(!(isitem(A) && get_dist(src, A) <= 1) && (client && (client.prefs.toggle_prefs & TOGGLE_MIDDLE_MOUSE_SWAP_HANDS)))
swap_hand()
From 3c8c4f2e9e5fe2c4797aa2257a16ed00be7f77e0 Mon Sep 17 00:00:00 2001
From: cm13-github <128137806+cm13-github@users.noreply.github.com>
Date: Thu, 14 Mar 2024 11:51:42 +0000
Subject: [PATCH 10/10] Automatic changelog for PR #5899 [ci skip]
---
html/changelogs/AutoChangeLog-pr-5899.yml | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-5899.yml
diff --git a/html/changelogs/AutoChangeLog-pr-5899.yml b/html/changelogs/AutoChangeLog-pr-5899.yml
new file mode 100644
index 000000000000..9d22f5aa9aeb
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-5899.yml
@@ -0,0 +1,4 @@
+author: "Segrain"
+delete-after: True
+changes:
+ - qol: "Middleclicking beds/chairs/etc is now a shortcut for buckling to them."
\ No newline at end of file