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