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/_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() diff --git a/code/datums/diseases/black_goo.dm b/code/datums/diseases/black_goo.dm index 5af9f9c029b4..a5f67c8445be 100644 --- a/code/datums/diseases/black_goo.dm +++ b/code/datums/diseases/black_goo.dm @@ -257,7 +257,6 @@ /obj/item/reagent_container/glass/bottle/labeled_black_goo_cure name = "\"Pathogen\" cure bottle" desc = "The bottle has a biohazard symbol on the front, and has a label, designating its use against Agent A0-3959X.91–15, colloquially known as the \"Black Goo\"." - icon_state = "bottle20" /obj/item/reagent_container/glass/bottle/labeled_black_goo_cure/Initialize() . = ..() 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. 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/game/machinery/ARES/ARES_interface.dm b/code/game/machinery/ARES/ARES_interface.dm index cfe3fe2669bc..dd99240b2550 100644 --- a/code/game/machinery/ARES/ARES_interface.dm +++ b/code/game/machinery/ARES/ARES_interface.dm @@ -218,17 +218,17 @@ return playsound(src, "keyboard_alt", 15, 1) + var/mob/living/carbon/human/operator = ui.user switch (action) if("go_back") if(!last_menu) - return to_chat(usr, SPAN_WARNING("Error, no previous page detected.")) + return to_chat(operator, SPAN_WARNING("Error, no previous page detected.")) var/temp_holder = current_menu current_menu = last_menu last_menu = temp_holder if("login") - var/mob/living/carbon/human/operator = usr var/obj/item/card/id/idcard = operator.get_active_hand() if(istype(idcard)) authentication = get_ares_access(idcard) @@ -239,7 +239,7 @@ authentication = get_ares_access(idcard) last_login = idcard.registered_name else - to_chat(usr, SPAN_WARNING("You require an ID card to access this terminal!")) + to_chat(operator, SPAN_WARNING("You require an ID card to access this terminal!")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE if(authentication) @@ -247,14 +247,14 @@ current_menu = "main" if("sudo") - var/new_user = tgui_input_text(usr, "Enter Sudo Username", "Sudo User", encode = FALSE) + var/new_user = tgui_input_text(operator, "Enter Sudo Username", "Sudo User", encode = FALSE) if(new_user) if(new_user == sudo_holder) last_login = sudo_holder sudo_holder = null return FALSE if(new_user == last_login) - to_chat(usr, SPAN_WARNING("Already remote logged in as this user.")) + to_chat(operator, SPAN_WARNING("Already remote logged in as this user.")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE sudo_holder = last_login @@ -370,9 +370,9 @@ datacore.records_talking -= conversation if("message_ares") - var/message = tgui_input_text(usr, "What do you wish to say to ARES?", "ARES Message", encode = FALSE) + var/message = tgui_input_text(operator, "What do you wish to say to ARES?", "ARES Message", encode = FALSE) if(message) - message_ares(message, usr, params["active_convo"]) + message_ares(message, operator, params["active_convo"]) if("read_record") var/datum/ares_record/deleted_talk/conversation = locate(params["record"]) @@ -385,36 +385,36 @@ // -- Emergency Buttons -- // if("general_quarters") if(!COOLDOWN_FINISHED(datacore, ares_quarters_cooldown)) - to_chat(usr, SPAN_WARNING("It has not been long enough since the last General Quarters call!")) + to_chat(operator, SPAN_WARNING("It has not been long enough since the last General Quarters call!")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE if(GLOB.security_level < SEC_LEVEL_RED) set_security_level(SEC_LEVEL_RED, no_sound = TRUE, announce = FALSE) shipwide_ai_announcement("ATTENTION! GENERAL QUARTERS. ALL HANDS, MAN YOUR BATTLESTATIONS.", MAIN_AI_SYSTEM, 'sound/effects/GQfullcall.ogg') - log_game("[key_name(usr)] has called for general quarters via ARES.") - message_admins("[key_name_admin(usr)] has called for general quarters via ARES.") + log_game("[key_name(operator)] has called for general quarters via ARES.") + message_admins("[key_name_admin(operator)] has called for general quarters via ARES.") log_ares_security("General Quarters", "[last_login] has called for general quarters via ARES.") COOLDOWN_START(datacore, ares_quarters_cooldown, 10 MINUTES) . = TRUE if("evacuation_start") if(GLOB.security_level < SEC_LEVEL_RED) - to_chat(usr, SPAN_WARNING("The ship must be under red alert in order to enact evacuation procedures.")) + to_chat(operator, SPAN_WARNING("The ship must be under red alert in order to enact evacuation procedures.")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE if(SShijack.evac_admin_denied) - to_chat(usr, SPAN_WARNING("The USCM has placed a lock on deploying the evacuation pods.")) + to_chat(operator, SPAN_WARNING("The USCM has placed a lock on deploying the evacuation pods.")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE if(!SShijack.initiate_evacuation()) - to_chat(usr, SPAN_WARNING("You are unable to initiate an evacuation procedure right now!")) + to_chat(operator, SPAN_WARNING("You are unable to initiate an evacuation procedure right now!")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE - log_game("[key_name(usr)] has called for an emergency evacuation via ARES.") - message_admins("[key_name_admin(usr)] has called for an emergency evacuation via ARES.") + log_game("[key_name(operator)] has called for an emergency evacuation via ARES.") + message_admins("[key_name_admin(operator)] has called for an emergency evacuation via ARES.") log_ares_security("Initiate Evacuation", "[last_login] has called for an emergency evacuation via ARES.") . = TRUE @@ -422,27 +422,27 @@ if(!SSticker.mode) return FALSE //Not a game mode? if(world.time < DISTRESS_TIME_LOCK) - to_chat(usr, SPAN_WARNING("You have been here for less than six minutes... what could you possibly have done!")) + to_chat(operator, SPAN_WARNING("You have been here for less than six minutes... what could you possibly have done!")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE if(!COOLDOWN_FINISHED(datacore, ares_distress_cooldown)) - to_chat(usr, SPAN_WARNING("The distress launcher is cooling down!")) + to_chat(operator, SPAN_WARNING("The distress launcher is cooling down!")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE if(GLOB.security_level == SEC_LEVEL_DELTA) - to_chat(usr, SPAN_WARNING("The ship is already undergoing self destruct procedures!")) + to_chat(operator, SPAN_WARNING("The ship is already undergoing self destruct procedures!")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE if(GLOB.security_level < SEC_LEVEL_RED) - to_chat(usr, SPAN_WARNING("The ship must be under red alert to launch a distress beacon!")) + to_chat(operator, SPAN_WARNING("The ship must be under red alert to launch a distress beacon!")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE for(var/client/admin in GLOB.admins) if((R_ADMIN|R_MOD) & admin.admin_holder.rights) playsound_client(admin,'sound/effects/sos-morse-code.ogg',10) - SSticker.mode.request_ert(usr, TRUE) - to_chat(usr, SPAN_NOTICE("A distress beacon request has been sent to USCM High Command.")) + SSticker.mode.request_ert(operator, TRUE) + to_chat(operator, SPAN_NOTICE("A distress beacon request has been sent to USCM High Command.")) COOLDOWN_START(datacore, ares_distress_cooldown, COOLDOWN_COMM_REQUEST) return TRUE @@ -450,25 +450,25 @@ if(!SSticker.mode) return FALSE //Not a game mode? if(world.time < NUCLEAR_TIME_LOCK) - to_chat(usr, SPAN_WARNING("It is too soon to request Nuclear Ordnance!")) + to_chat(operator, SPAN_WARNING("It is too soon to request Nuclear Ordnance!")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE if(!COOLDOWN_FINISHED(datacore, ares_nuclear_cooldown)) - to_chat(usr, SPAN_WARNING("The ordnance request frequency is garbled, wait for reset!")) + to_chat(operator, SPAN_WARNING("The ordnance request frequency is garbled, wait for reset!")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE if(GLOB.security_level == SEC_LEVEL_DELTA || SSticker.mode.is_in_endgame) - to_chat(usr, SPAN_WARNING("The mission has failed catastrophically, what do you want a nuke for?!")) + to_chat(operator, SPAN_WARNING("The mission has failed catastrophically, what do you want a nuke for?!")) playsound(src, 'sound/machines/buzz-two.ogg', 15, 1) return FALSE - var/reason = tgui_input_text(usr, "Please enter reason nuclear ordnance is required.", "Reason for Nuclear Ordnance") + var/reason = tgui_input_text(operator, "Please enter reason nuclear ordnance is required.", "Reason for Nuclear Ordnance") if(!reason) return FALSE for(var/client/admin in GLOB.admins) if((R_ADMIN|R_MOD) & admin.admin_holder.rights) playsound_client(admin,'sound/effects/sos-morse-code.ogg',10) - message_admins("[key_name(usr)] has requested use of Nuclear Ordnance (via ARES)! Reason: [reason] [CC_MARK(usr)] (APPROVE) (DENY) [ADMIN_JMP_USER(usr)] [CC_REPLY(usr)]") - to_chat(usr, SPAN_NOTICE("A nuclear ordnance request has been sent to USCM High Command for the following reason: [reason]")) + message_admins("[key_name(operator)] has requested use of Nuclear Ordnance (via ARES)! Reason: [reason] [CC_MARK(operator)] (APPROVE) (DENY) [ADMIN_JMP_USER(operator)] [CC_REPLY(operator)]") + to_chat(operator, SPAN_NOTICE("A nuclear ordnance request has been sent to USCM High Command for the following reason: [reason]")) log_ares_security("Nuclear Ordnance Request", "[last_login] has sent a request for nuclear ordnance for the following reason: [reason]") if(ares_can_interface()) ai_silent_announcement("[last_login] has sent a request for nuclear ordnance to USCM High Command.", ".V") diff --git a/code/game/machinery/ARES/ARES_interface_apollo.dm b/code/game/machinery/ARES/ARES_interface_apollo.dm index 56283417ae05..c1c936676dc5 100644 --- a/code/game/machinery/ARES/ARES_interface_apollo.dm +++ b/code/game/machinery/ARES/ARES_interface_apollo.dm @@ -18,6 +18,9 @@ /// The last person to login. var/last_login + /// Notification sound + var/notify_sounds = TRUE + /obj/structure/machinery/computer/working_joe/proc/link_systems(datum/ares_link/new_link = GLOB.ares_link, override) if(link && !override) @@ -34,6 +37,16 @@ link_systems(override = FALSE) . = ..() +/obj/structure/machinery/computer/working_joe/proc/notify() + if(notify_sounds) + playsound(src, 'sound/machines/pda_ping.ogg', 25, 0) + +/obj/structure/machinery/computer/working_joe/proc/send_notifcation() + for(var/obj/structure/machinery/computer/working_joe/ticketer as anything in link.ticket_computers) + if(ticketer == src) + continue + ticketer.notify() + /obj/structure/machinery/computer/working_joe/proc/delink() if(link) link.ticket_computers -= src @@ -76,8 +89,9 @@ data["access_log"] = list() data["access_log"] += datacore.apollo_login_list - data["apollo_log"] = list() - data["apollo_log"] += datacore.apollo_log + data["apollo_log"] = datacore.apollo_log + + data["notify_sounds"] = notify_sounds var/list/logged_maintenance = list() for(var/datum/ares_ticket/maintenance/maint_ticket as anything in link.tickets_maintenance) @@ -142,12 +156,12 @@ return var/playsound = TRUE - var/mob/living/carbon/human/operator = usr + var/mob/living/carbon/human/operator = ui.user switch (action) if("go_back") if(!last_menu) - return to_chat(usr, SPAN_WARNING("Error, no previous page detected.")) + return to_chat(operator, SPAN_WARNING("Error, no previous page detected.")) var/temp_holder = current_menu current_menu = last_menu last_menu = temp_holder @@ -198,6 +212,9 @@ last_menu = current_menu current_menu = "maint_claim" + if("toggle_sound") + notify_sounds = !notify_sounds + if("new_report") var/priority_report = FALSE var/maint_type = tgui_input_list(operator, "What is the type of maintenance item you wish to report?", "Report Category", GLOB.maintenance_categories, 30 SECONDS) @@ -223,6 +240,8 @@ link.tickets_maintenance += maint_ticket if(priority_report) ares_apollo_talk("Priority Maintenance Report: [maint_type] - ID [maint_ticket.ticket_id]. Seek and resolve.") + else + send_notifcation() log_game("ARES: Maintenance Ticket '\ref[maint_ticket]' created by [key_name(operator)] as [last_login] with Category '[maint_type]' and Details of '[details]'.") return TRUE return FALSE @@ -235,14 +254,14 @@ var/assigned = ticket.ticket_assignee if(assigned) if(assigned == last_login) - var/prompt = tgui_alert(usr, "You already claimed this ticket! Do you wish to drop your claim?", "Unclaim ticket", list("Yes", "No")) + var/prompt = tgui_alert(operator, "You already claimed this ticket! Do you wish to drop your claim?", "Unclaim ticket", list("Yes", "No")) if(prompt != "Yes") return FALSE /// set ticket back to pending ticket.ticket_assignee = null ticket.ticket_status = TICKET_PENDING return claim - var/choice = tgui_alert(usr, "This ticket has already been claimed by [assigned]! Do you wish to override their claim?", "Claim Override", list("Yes", "No")) + var/choice = tgui_alert(operator, "This ticket has already been claimed by [assigned]! Do you wish to override their claim?", "Claim Override", list("Yes", "No")) if(choice != "Yes") claim = FALSE if(claim) @@ -255,12 +274,14 @@ if(!istype(ticket)) return FALSE if(ticket.ticket_submitter != last_login) - to_chat(usr, SPAN_WARNING("You cannot cancel a ticket that does not belong to you!")) + to_chat(operator, SPAN_WARNING("You cannot cancel a ticket that does not belong to you!")) return FALSE - to_chat(usr, SPAN_WARNING("[ticket.ticket_type] [ticket.ticket_id] has been cancelled.")) + to_chat(operator, SPAN_WARNING("[ticket.ticket_type] [ticket.ticket_id] has been cancelled.")) ticket.ticket_status = TICKET_CANCELLED if(ticket.ticket_priority) ares_apollo_talk("Priority [ticket.ticket_type] [ticket.ticket_id] has been cancelled.") + else + send_notifcation() return TRUE if("mark_ticket") @@ -268,9 +289,9 @@ if(!istype(ticket)) return FALSE if(ticket.ticket_assignee != last_login && ticket.ticket_assignee) //must be claimed by you or unclaimed.) - to_chat(usr, SPAN_WARNING("You cannot update a ticket that is not assigned to you!")) + to_chat(operator, SPAN_WARNING("You cannot update a ticket that is not assigned to you!")) return FALSE - var/choice = tgui_alert(usr, "What do you wish to mark the ticket as?", "Mark", list(TICKET_COMPLETED, TICKET_REJECTED), 20 SECONDS) + var/choice = tgui_alert(operator, "What do you wish to mark the ticket as?", "Mark", list(TICKET_COMPLETED, TICKET_REJECTED), 20 SECONDS) switch(choice) if(TICKET_COMPLETED) ticket.ticket_status = TICKET_COMPLETED @@ -280,7 +301,9 @@ return FALSE if(ticket.ticket_priority) ares_apollo_talk("Priority [ticket.ticket_type] [ticket.ticket_id] has been [choice] by [last_login].") - to_chat(usr, SPAN_NOTICE("[ticket.ticket_type] [ticket.ticket_id] marked as [choice].")) + else + send_notifcation() + to_chat(operator, SPAN_NOTICE("[ticket.ticket_type] [ticket.ticket_id] marked as [choice].")) return TRUE if("new_access") @@ -328,8 +351,6 @@ break for(var/obj/item/card/id/identification in link.active_ids) - if(!istype(identification)) - continue if(identification.registered_gid != access_ticket.user_id_num) continue @@ -353,11 +374,9 @@ if("auth_access") playsound = FALSE var/datum/ares_ticket/access/access_ticket = locate(params["ticket"]) - if(!access_ticket) + if(!istype(access_ticket)) return FALSE for(var/obj/item/card/id/identification in link.waiting_ids) - if(!istype(identification)) - continue if(identification.registered_gid != access_ticket.user_id_num) continue identification.handle_ares_access(last_login, operator) @@ -366,8 +385,6 @@ ares_apollo_talk("Access Ticket [access_ticket.ticket_id]: [access_ticket.ticket_submitter] was granted access by [last_login].") return TRUE for(var/obj/item/card/id/identification in link.active_ids) - if(!istype(identification)) - continue if(identification.registered_gid != access_ticket.user_id_num) continue identification.handle_ares_access(last_login, operator) @@ -382,22 +399,29 @@ if(!istype(access_ticket)) return FALSE if(access_ticket.ticket_assignee != last_login && access_ticket.ticket_assignee) //must be claimed by you or unclaimed.) - to_chat(usr, SPAN_WARNING("You cannot update a ticket that is not assigned to you!")) + to_chat(operator, SPAN_WARNING("You cannot update a ticket that is not assigned to you!")) return FALSE access_ticket.ticket_status = TICKET_REJECTED - to_chat(usr, SPAN_NOTICE("[access_ticket.ticket_type] [access_ticket.ticket_id] marked as rejected.")) + to_chat(operator, SPAN_NOTICE("[access_ticket.ticket_type] [access_ticket.ticket_id] marked as rejected.")) ares_apollo_talk("Access Ticket [access_ticket.ticket_id]: [access_ticket.ticket_submitter] was rejected access by [last_login].") + for(var/obj/item/card/id/identification in link.waiting_ids) + if(identification.registered_gid != access_ticket.user_id_num) + continue + var/mob/living/carbon/human/id_owner = identification.registered_ref?.resolve() + if(id_owner) + to_chat(id_owner, SPAN_WARNING("AI visitation access rejected.")) + playsound_client(id_owner?.client, 'sound/machines/pda_ping.ogg', src, 25, 0) return TRUE if(playsound) playsound(src, "keyboard_alt", 15, 1) -/obj/item/card/id/proc/handle_ares_access(logged_in, mob/user) +/obj/item/card/id/proc/handle_ares_access(logged_in = MAIN_AI_SYSTEM, mob/user) var/operator = key_name(user) var/datum/ares_link/link = GLOB.ares_link if(logged_in == MAIN_AI_SYSTEM) if(!user) - operator = "[MAIN_AI_SYSTEM] (Sensor Trip)" + operator = "[MAIN_AI_SYSTEM] (Automated)" else operator = "[user.ckey]/([MAIN_AI_SYSTEM])" if(ACCESS_MARINE_AI_TEMP in access) @@ -405,10 +429,18 @@ link.active_ids -= src modification_log += "Temporary AI access revoked by [operator]" to_chat(user, SPAN_NOTICE("Access revoked from [registered_name].")) + var/mob/living/carbon/human/id_owner = registered_ref?.resolve() + if(id_owner) + to_chat(id_owner, SPAN_WARNING("AI visitation access revoked.")) + playsound_client(id_owner?.client, 'sound/machines/pda_ping.ogg', src, 25, 0) else access += ACCESS_MARINE_AI_TEMP modification_log += "Temporary AI access granted by [operator]" to_chat(user, SPAN_NOTICE("Access granted to [registered_name].")) link.waiting_ids -= src link.active_ids += src + var/mob/living/carbon/human/id_owner = registered_ref?.resolve() + if(id_owner) + to_chat(id_owner, SPAN_HELPFUL("AI visitation access granted.")) + playsound_client(id_owner?.client, 'sound/machines/pda_ping.ogg', src, 25, 0) return TRUE diff --git a/code/game/machinery/ARES/apollo_pda.dm b/code/game/machinery/ARES/apollo_pda.dm index 8df3faf79260..69e774cf0da3 100644 --- a/code/game/machinery/ARES/apollo_pda.dm +++ b/code/game/machinery/ARES/apollo_pda.dm @@ -19,6 +19,9 @@ /// The last person to login. var/last_login + /// Notification sound + var/notify_sounds = TRUE + /obj/item/device/working_joe_pda/proc/link_systems(datum/ares_link/new_link = GLOB.ares_link, override) if(link && !override) @@ -35,6 +38,16 @@ link_systems(override = FALSE) . = ..() +/obj/item/device/working_joe_pda/proc/notify() + if(notify_sounds) + playsound(src, 'sound/machines/pda_ping.ogg', 25, 0) + +/obj/item/device/working_joe_pda/proc/send_notifcation() + for(var/obj/item/device/working_joe_pda/ticketer as anything in link.ticket_computers) + if(ticketer == src) + continue + ticketer.notify() + /obj/item/device/working_joe_pda/proc/delink() if(link) link.ticket_computers -= src @@ -103,6 +116,8 @@ data["apollo_log"] = list() data["apollo_log"] += datacore.apollo_log + data["notify_sounds"] = notify_sounds + var/list/logged_maintenance = list() for(var/datum/ares_ticket/maintenance/maint_ticket as anything in link.tickets_maintenance) if(!istype(maint_ticket)) @@ -164,12 +179,12 @@ return var/playsound = TRUE - var/mob/living/carbon/human/operator = usr + var/mob/living/carbon/human/operator = ui.user switch (action) if("go_back") if(!last_menu) - return to_chat(usr, SPAN_WARNING("Error, no previous page detected.")) + return to_chat(operator, SPAN_WARNING("Error, no previous page detected.")) var/temp_holder = current_menu current_menu = last_menu last_menu = temp_holder @@ -223,6 +238,9 @@ last_menu = current_menu current_menu = "maint_claim" + if("toggle_sound") + notify_sounds = !notify_sounds + if("new_report") var/priority_report = FALSE var/maint_type = tgui_input_list(operator, "What is the type of maintenance item you wish to report?", "Report Category", GLOB.maintenance_categories, 30 SECONDS) @@ -248,6 +266,8 @@ link.tickets_maintenance += maint_ticket if(priority_report) ares_apollo_talk("Priority Maintenance Report: [maint_type] - ID [maint_ticket.ticket_id]. Seek and resolve.") + else + send_notifcation() log_game("ARES: Maintenance Ticket '\ref[maint_ticket]' created by [key_name(operator)] as [last_login] with Category '[maint_type]' and Details of '[details]'.") return TRUE return FALSE @@ -260,14 +280,14 @@ var/assigned = ticket.ticket_assignee if(assigned) if(assigned == last_login) - var/prompt = tgui_alert(usr, "You already claimed this ticket! Do you wish to drop your claim?", "Unclaim ticket", list("Yes", "No")) + var/prompt = tgui_alert(operator, "You already claimed this ticket! Do you wish to drop your claim?", "Unclaim ticket", list("Yes", "No")) if(prompt != "Yes") return FALSE /// set ticket back to pending ticket.ticket_assignee = null ticket.ticket_status = TICKET_PENDING return claim - var/choice = tgui_alert(usr, "This ticket has already been claimed by [assigned]! Do you wish to override their claim?", "Claim Override", list("Yes", "No")) + var/choice = tgui_alert(operator, "This ticket has already been claimed by [assigned]! Do you wish to override their claim?", "Claim Override", list("Yes", "No")) if(choice != "Yes") claim = FALSE if(claim) @@ -280,12 +300,14 @@ if(!istype(ticket)) return FALSE if(ticket.ticket_submitter != last_login) - to_chat(usr, SPAN_WARNING("You cannot cancel a ticket that does not belong to you!")) + to_chat(operator, SPAN_WARNING("You cannot cancel a ticket that does not belong to you!")) return FALSE - to_chat(usr, SPAN_WARNING("[ticket.ticket_type] [ticket.ticket_id] has been cancelled.")) + to_chat(operator, SPAN_WARNING("[ticket.ticket_type] [ticket.ticket_id] has been cancelled.")) ticket.ticket_status = TICKET_CANCELLED if(ticket.ticket_priority) ares_apollo_talk("Priority [ticket.ticket_type] [ticket.ticket_id] has been cancelled.") + else + send_notifcation() return TRUE if("mark_ticket") @@ -293,9 +315,9 @@ if(!istype(ticket)) return FALSE if(ticket.ticket_assignee != last_login && ticket.ticket_assignee) //must be claimed by you or unclaimed.) - to_chat(usr, SPAN_WARNING("You cannot update a ticket that is not assigned to you!")) + to_chat(operator, SPAN_WARNING("You cannot update a ticket that is not assigned to you!")) return FALSE - var/choice = tgui_alert(usr, "What do you wish to mark the ticket as?", "Mark", list(TICKET_COMPLETED, TICKET_REJECTED), 20 SECONDS) + var/choice = tgui_alert(operator, "What do you wish to mark the ticket as?", "Mark", list(TICKET_COMPLETED, TICKET_REJECTED), 20 SECONDS) switch(choice) if(TICKET_COMPLETED) ticket.ticket_status = TICKET_COMPLETED @@ -305,7 +327,9 @@ return FALSE if(ticket.ticket_priority) ares_apollo_talk("Priority [ticket.ticket_type] [ticket.ticket_id] has been [choice] by [last_login].") - to_chat(usr, SPAN_NOTICE("[ticket.ticket_type] [ticket.ticket_id] marked as [choice].")) + else + send_notifcation() + to_chat(operator, SPAN_NOTICE("[ticket.ticket_type] [ticket.ticket_id] marked as [choice].")) return TRUE if("new_access") @@ -353,8 +377,6 @@ break for(var/obj/item/card/id/identification in link.active_ids) - if(!istype(identification)) - continue if(identification.registered_gid != access_ticket.user_id_num) continue @@ -381,8 +403,6 @@ if(!access_ticket) return FALSE for(var/obj/item/card/id/identification in link.waiting_ids) - if(!istype(identification)) - continue if(identification.registered_gid != access_ticket.user_id_num) continue identification.handle_ares_access(last_login, operator) @@ -391,8 +411,6 @@ ares_apollo_talk("Access Ticket [access_ticket.ticket_id]: [access_ticket.ticket_submitter] was granted access by [last_login].") return TRUE for(var/obj/item/card/id/identification in link.active_ids) - if(!istype(identification)) - continue if(identification.registered_gid != access_ticket.user_id_num) continue identification.handle_ares_access(last_login, operator) @@ -407,11 +425,18 @@ if(!istype(access_ticket)) return FALSE if(access_ticket.ticket_assignee != last_login && access_ticket.ticket_assignee) //must be claimed by you or unclaimed.) - to_chat(usr, SPAN_WARNING("You cannot update a ticket that is not assigned to you!")) + to_chat(operator, SPAN_WARNING("You cannot update a ticket that is not assigned to you!")) return FALSE access_ticket.ticket_status = TICKET_REJECTED - to_chat(usr, SPAN_NOTICE("[access_ticket.ticket_type] [access_ticket.ticket_id] marked as rejected.")) + to_chat(operator, SPAN_NOTICE("[access_ticket.ticket_type] [access_ticket.ticket_id] marked as rejected.")) ares_apollo_talk("Access Ticket [access_ticket.ticket_id]: [access_ticket.ticket_submitter] was rejected access by [last_login].") + for(var/obj/item/card/id/identification in link.waiting_ids) + if(identification.registered_gid != access_ticket.user_id_num) + continue + var/mob/living/carbon/human/id_owner = identification.registered_ref?.resolve() + if(id_owner) + to_chat(id_owner, SPAN_WARNING("AI visitation access rejected.")) + playsound_client(id_owner?.client, 'sound/machines/pda_ping.ogg', src, 25, 0) return TRUE if(playsound) diff --git a/code/game/machinery/autolathe_datums.dm b/code/game/machinery/autolathe_datums.dm index e11fc2d4844d..01a40b3638f6 100644 --- a/code/game/machinery/autolathe_datums.dm +++ b/code/game/machinery/autolathe_datums.dm @@ -409,7 +409,7 @@ path = /obj/item/reagent_container/blood /datum/autolathe/recipe/medilathe/bluespace - name = "bluespace beaker" + name = "high-capacity beaker" path = /obj/item/reagent_container/glass/beaker/bluespace /datum/autolathe/recipe/medilathe/bonesetter diff --git a/code/game/machinery/colony_floodlights.dm b/code/game/machinery/colony_floodlights.dm index eef05df3352e..13478381e38e 100644 --- a/code/game/machinery/colony_floodlights.dm +++ b/code/game/machinery/colony_floodlights.dm @@ -1,18 +1,19 @@ //Putting these here since it's power-related /obj/structure/machinery/colony_floodlight_switch - name = "Colony Floodlight Switch" + name = "colony floodlight switch" icon = 'icons/obj/structures/machinery/power.dmi' icon_state = "panelnopower" desc = "This switch controls the floodlights surrounding the archaeology complex. It only functions when there is power." density = FALSE anchored = TRUE - var/ispowered = FALSE - var/turned_on = 0 //has to be toggled in engineering use_power = USE_POWER_IDLE unslashable = TRUE unacidable = TRUE - var/list/floodlist = list() // This will save our list of floodlights on the map power_machine = TRUE + var/ispowered = FALSE + var/turned_on = FALSE //has to be toggled in engineering + ///All floodlights under our control + var/list/floodlist = list() /obj/structure/machinery/colony_floodlight_switch/Initialize(mapload, ...) . = ..() @@ -20,9 +21,9 @@ /obj/structure/machinery/colony_floodlight_switch/LateInitialize() . = ..() - for(var/obj/structure/machinery/colony_floodlight/F in GLOB.machines) - floodlist += F - F.fswitch = src + for(var/obj/structure/machinery/colony_floodlight/floodlight in GLOB.machines) + floodlist += floodlight + floodlight.fswitch = src start_processing() /obj/structure/machinery/colony_floodlight_switch/Destroy() @@ -31,7 +32,6 @@ floodlist = null return ..() - /obj/structure/machinery/colony_floodlight_switch/update_icon() if(!ispowered) icon_state = "panelnopower" @@ -42,10 +42,10 @@ /obj/structure/machinery/colony_floodlight_switch/process() var/lightpower = 0 - for(var/obj/structure/machinery/colony_floodlight/C in floodlist) - if(!C.is_lit) + for(var/obj/structure/machinery/colony_floodlight/floodlight as anything in floodlist) + if(!floodlight.is_lit) continue - lightpower += C.power_tick + lightpower += floodlight.power_tick use_power(lightpower) /obj/structure/machinery/colony_floodlight_switch/power_change() @@ -54,37 +54,29 @@ if(ispowered && turned_on) toggle_lights() ispowered = FALSE - turned_on = 0 + turned_on = FALSE update_icon() else ispowered = TRUE update_icon() /obj/structure/machinery/colony_floodlight_switch/proc/toggle_lights() - for(var/obj/structure/machinery/colony_floodlight/F in floodlist) - spawn(rand(0,50)) - F.is_lit = !F.is_lit - if(!F.damaged) - if(F.is_lit) //Shut it down - F.set_light(F.lum_value) - else - F.set_light(0) - F.update_icon() - return 0 + for(var/obj/structure/machinery/colony_floodlight/floodlight as anything in floodlist) + addtimer(CALLBACK(floodlight, TYPE_PROC_REF(/obj/structure/machinery/colony_floodlight, toggle_light)), rand(0, 5 SECONDS)) /obj/structure/machinery/colony_floodlight_switch/attack_hand(mob/user as mob) if(!ishuman(user)) to_chat(user, "Nice try.") - return 0 + return FALSE if(!ispowered) to_chat(user, "Nothing happens.") - return 0 + return FALSE playsound(src,'sound/items/Deconstruct.ogg', 30, 1) use_power(5) toggle_lights() - turned_on = !(src.turned_on) + turned_on = !turned_on update_icon() - return 1 + return TRUE #define FLOODLIGHT_REPAIR_UNSCREW 0 @@ -94,21 +86,26 @@ #define FLOODLIGHT_REPAIR_SCREW 4 /obj/structure/machinery/colony_floodlight - name = "Colony Floodlight" + name = "colony floodlight" icon = 'icons/obj/structures/machinery/big_floodlight.dmi' icon_state = "flood_s_off" density = TRUE anchored = TRUE layer = ABOVE_XENO_LAYER - var/damaged = 0 //Can be smashed by xenos - var/is_lit = 0 //whether the floodlight is switched to on or off. Does not necessarily mean it emits light. unslashable = TRUE unacidable = TRUE - var/power_tick = 50 // power each floodlight takes up per process use_power = USE_POWER_NONE //It's the switch that uses the actual power, not the lights - var/obj/structure/machinery/colony_floodlight_switch/fswitch = null //Reverse lookup for power grabbing in area + needs_power = FALSE + ///Whether it has been smashed by xenos + var/damaged = FALSE + ///Whether the floodlight is switched to on or off. Does not necessarily mean it emits light. + var/is_lit = FALSE + ///The power each floodlight takes up per process + var/power_tick = 50 + ///Reverse lookup for power grabbing in area + var/obj/structure/machinery/colony_floodlight_switch/fswitch = null var/lum_value = 7 - var/repair_state = 0 + var/repair_state = FLOODLIGHT_REPAIR_UNSCREW health = 150 /obj/structure/machinery/colony_floodlight/Destroy() @@ -130,13 +127,13 @@ if(HAS_TRAIT(I, TRAIT_TOOL_SCREWDRIVER)) if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI)) to_chat(user, SPAN_WARNING("You have no clue how to repair [src].")) - return 0 + return FALSE if(repair_state == FLOODLIGHT_REPAIR_UNSCREW) playsound(loc, 'sound/items/Screwdriver.ogg', 25, 1) user.visible_message(SPAN_NOTICE("[user] starts unscrewing [src]'s maintenance hatch."), \ SPAN_NOTICE("You start unscrewing [src]'s maintenance hatch.")) - if(do_after(user, 20, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) + if(do_after(user, 2 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) if(QDELETED(src) || repair_state != FLOODLIGHT_REPAIR_UNSCREW) return playsound(loc, 'sound/items/Screwdriver.ogg', 25, 1) @@ -148,11 +145,11 @@ playsound(loc, 'sound/items/Screwdriver.ogg', 25, 1) user.visible_message(SPAN_NOTICE("[user] starts screwing [src]'s maintenance hatch closed."), \ SPAN_NOTICE("You start screwing [src]'s maintenance hatch closed.")) - if(do_after(user, 20, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) + if(do_after(user, 2 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) if(QDELETED(src) || repair_state != FLOODLIGHT_REPAIR_SCREW) return playsound(loc, 'sound/items/Screwdriver.ogg', 25, 1) - damaged = 0 + damaged = FALSE repair_state = FLOODLIGHT_REPAIR_UNSCREW health = initial(health) user.visible_message(SPAN_NOTICE("[user] screws [src]'s maintenance hatch closed."), \ @@ -165,74 +162,100 @@ else if(HAS_TRAIT(I, TRAIT_TOOL_CROWBAR)) if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI)) to_chat(user, SPAN_WARNING("You have no clue how to repair [src].")) - return 0 + return FALSE if(repair_state == FLOODLIGHT_REPAIR_CROWBAR) - playsound(src.loc, 'sound/items/Crowbar.ogg', 25, 1) - user.visible_message(SPAN_NOTICE("[user] starts prying [src]'s maintenance hatch open."),\ - SPAN_NOTICE("You start prying [src]'s maintenance hatch open.")) - if(do_after(user, 20, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) + playsound(loc, 'sound/items/Crowbar.ogg', 25, 1) + user.visible_message(SPAN_NOTICE("[user] starts prying [src]'s damaged lighting assembly out."),\ + SPAN_NOTICE("You start prying [src]'s damaged lighting assembly out.")) + if(do_after(user, 2 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) if(QDELETED(src) || repair_state != FLOODLIGHT_REPAIR_CROWBAR) return - playsound(src.loc, 'sound/items/Crowbar.ogg', 25, 1) + playsound(loc, 'sound/items/Crowbar.ogg', 25, 1) repair_state = FLOODLIGHT_REPAIR_WELD - user.visible_message(SPAN_NOTICE("[user] pries [src]'s maintenance hatch open."),\ - SPAN_NOTICE("You pry [src]'s maintenance hatch open.")) + user.visible_message(SPAN_NOTICE("[user] pries [src]'s damaged lighting assembly out."),\ + SPAN_NOTICE("You pry [src]'s damaged lighting assembly out.")) return TRUE else if(iswelder(I)) if(!HAS_TRAIT(I, TRAIT_TOOL_BLOWTORCH)) to_chat(user, SPAN_WARNING("You need a stronger blowtorch!")) return - var/obj/item/tool/weldingtool/WT = I + var/obj/item/tool/weldingtool/welder = I if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI)) to_chat(user, SPAN_WARNING("You have no clue how to repair [src].")) - return 0 + return FALSE if(repair_state == FLOODLIGHT_REPAIR_WELD) - if(WT.remove_fuel(1, user)) + if(welder.remove_fuel(1, user)) playsound(loc, 'sound/items/weldingtool_weld.ogg', 25) user.visible_message(SPAN_NOTICE("[user] starts welding [src]'s damage."), SPAN_NOTICE("You start welding [src]'s damage.")) - if(do_after(user, 40, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(QDELETED(src) || !WT.isOn() || repair_state != FLOODLIGHT_REPAIR_WELD) + if(do_after(user, 4 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) + if(QDELETED(src) || !welder.isOn() || repair_state != FLOODLIGHT_REPAIR_WELD) return playsound(loc, 'sound/items/Welder2.ogg', 25, 1) repair_state = FLOODLIGHT_REPAIR_CABLE user.visible_message(SPAN_NOTICE("[user] welds [src]'s damage."), SPAN_NOTICE("You weld [src]'s damage.")) - return 1 + return TRUE else to_chat(user, SPAN_WARNING("You need more welding fuel to complete this task.")) return TRUE else if(iscoil(I)) - var/obj/item/stack/cable_coil/C = I + var/obj/item/stack/cable_coil/coil = I if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI)) to_chat(user, SPAN_WARNING("You have no clue how to repair [src].")) - return 0 + return FALSE if(repair_state == FLOODLIGHT_REPAIR_CABLE) - if(C.get_amount() < 2) + if(coil.get_amount() < 2) to_chat(user, SPAN_WARNING("You need two coils of wire to replace the damaged cables.")) return playsound(loc, 'sound/items/Deconstruct.ogg', 25, 1) user.visible_message(SPAN_NOTICE("[user] starts replacing [src]'s damaged cables."),\ SPAN_NOTICE("You start replacing [src]'s damaged cables.")) - if(do_after(user, 20, INTERRUPT_ALL, BUSY_ICON_GENERIC)) + if(do_after(user, 2 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC)) if(QDELETED(src) || repair_state != FLOODLIGHT_REPAIR_CABLE) return - if(C.use(2)) + if(coil.use(2)) playsound(loc, 'sound/items/Deconstruct.ogg', 25, 1) repair_state = FLOODLIGHT_REPAIR_SCREW - user.visible_message(SPAN_NOTICE("[user] starts replaces [src]'s damaged cables."),\ + user.visible_message(SPAN_NOTICE("[user] replaces [src]'s damaged cables."),\ SPAN_NOTICE("You replace [src]'s damaged cables.")) return TRUE + else if(istype(I, /obj/item/device/lightreplacer)) + if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI)) + to_chat(user, SPAN_WARNING("You have no clue how to repair [src].")) + return FALSE - ..() - return 0 + if(repair_state == FLOODLIGHT_REPAIR_UNSCREW) + to_chat(user, SPAN_WARNING("You need to unscrew [src]'s maintenance hatch.")) + return FALSE + if(repair_state == FLOODLIGHT_REPAIR_SCREW) + to_chat(user, SPAN_WARNING("You need to screw [src]'s maintenance hatch.")) + return FALSE + + var/obj/item/device/lightreplacer/replacer = I + if(!replacer.CanUse(user)) + to_chat(user, replacer.failmsg) + return FALSE + playsound(loc, 'sound/items/Crowbar.ogg', 25, 1) + user.visible_message(SPAN_NOTICE("[user] starts replacing [src]'s damaged lighting assembly."),\ + SPAN_NOTICE("You start replacing [src]'s damaged lighting assembly.")) + if(do_after(user, 2 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC)) + if(QDELETED(src) || repair_state == FLOODLIGHT_REPAIR_SCREW) + return + replacer.Use(user) + repair_state = FLOODLIGHT_REPAIR_SCREW + user.visible_message(SPAN_NOTICE("[user] replaces [src]'s damaged lighting assembly."),\ + SPAN_NOTICE("You replace [src]'s damaged lighting assembly.")) + return TRUE + + return ..() /obj/structure/machinery/colony_floodlight/attack_hand(mob/user) if(ishuman(user)) @@ -240,8 +263,8 @@ to_chat(user, SPAN_WARNING("[src] is damaged.")) else if(!is_lit) to_chat(user, SPAN_WARNING("Nothing happens. Looks like it's powered elsewhere.")) - return 0 - ..() + return FALSE + return ..() /obj/structure/machinery/colony_floodlight/get_examine_text(mob/user) . = ..() @@ -251,13 +274,20 @@ if(skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI)) switch(repair_state) if(FLOODLIGHT_REPAIR_UNSCREW) . += SPAN_INFO("You must first unscrew its maintenance hatch.") - if(FLOODLIGHT_REPAIR_CROWBAR) . += SPAN_INFO("You must crowbar its maintenance hatch open.") + if(FLOODLIGHT_REPAIR_CROWBAR) . += SPAN_INFO("You must crowbar its lighting assembly out or use a light replacer.") if(FLOODLIGHT_REPAIR_WELD) . += SPAN_INFO("You must weld the damage to it.") if(FLOODLIGHT_REPAIR_CABLE) . += SPAN_INFO("You must replace its damaged cables.") if(FLOODLIGHT_REPAIR_SCREW) . += SPAN_INFO("You must screw its maintenance hatch closed.") else if(!is_lit) . += SPAN_INFO("It doesn't seem powered.") +/obj/structure/machinery/colony_floodlight/proc/toggle_light() + is_lit = !is_lit + if(!damaged) + set_light(is_lit ? lum_value : 0) + update_icon() + return is_lit + #undef FLOODLIGHT_REPAIR_UNSCREW #undef FLOODLIGHT_REPAIR_CROWBAR #undef FLOODLIGHT_REPAIR_WELD 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_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), 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), diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 9addf3346a39..31158d055327 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -67,7 +67,7 @@ /// The name registered_name on the card var/registered_name = "Unknown" - var/registered_ref = null + var/datum/weakref/registered_ref = null var/registered_gid = 0 flags_equip_slot = SLOT_ID diff --git a/code/game/objects/items/reagent_containers/glass.dm b/code/game/objects/items/reagent_containers/glass.dm index 2a7bde748fba..fc8d03f5d24d 100644 --- a/code/game/objects/items/reagent_containers/glass.dm +++ b/code/game/objects/items/reagent_containers/glass.dm @@ -217,17 +217,16 @@ overlays.Cut() if(reagents && reagents.total_volume) - var/image/filling = image('icons/obj/items/reagentfillings.dmi', src, "[icon_state]10") + var/image/filling = image('icons/obj/items/reagentfillings.dmi', src, "[icon_state]-20") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) - if(0 to 9) filling.icon_state = "[icon_state]-10" - if(10 to 24) filling.icon_state = "[icon_state]10" - if(25 to 49) filling.icon_state = "[icon_state]25" - if(50 to 74) filling.icon_state = "[icon_state]50" - if(75 to 79) filling.icon_state = "[icon_state]75" - if(80 to 90) filling.icon_state = "[icon_state]80" - if(91 to INFINITY) filling.icon_state = "[icon_state]100" + if(0) filling.icon_state = null + if(1 to 20) filling.icon_state = "[icon_state]-20" + if(21 to 40) filling.icon_state = "[icon_state]-40" + if(41 to 60) filling.icon_state = "[icon_state]-60" + if(61 to 80) filling.icon_state = "[icon_state]-80" + if(81 to INFINITY) filling.icon_state = "[icon_state]-100" filling.color = mix_color_from_reagents(reagents.reagent_list) overlays += filling @@ -345,8 +344,8 @@ flags_atom = FPRINT|OPENCONTAINER|NOREACT /obj/item/reagent_container/glass/beaker/bluespace - name = "bluespace beaker" - desc = "A beaker with an enlarged holding capacity, made with blue-tinted plexiglass in order to withstand greater pressure - affectionately nicknamed \"bluespace\". Can hold up to 300 units." + name = "high-capacity beaker" + desc = "A beaker with an enlarged holding capacity, made with blue-tinted plexiglass in order to withstand greater pressure. Can hold up to 300 units." icon_state = "beakerbluespace" matter = list("glass" = 10000) volume = 300 diff --git a/code/game/objects/items/reagent_containers/glass/bottle.dm b/code/game/objects/items/reagent_containers/glass/bottle.dm index 01eb751774e1..9e0215b535b6 100644 --- a/code/game/objects/items/reagent_containers/glass/bottle.dm +++ b/code/game/objects/items/reagent_containers/glass/bottle.dm @@ -4,13 +4,14 @@ name = "bottle" desc = "A small bottle." icon = 'icons/obj/items/chemistry.dmi' - icon_state = null + icon_state = "bottle-1" item_state = "atoxinbottle" amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5, 10, 15, 25, 30, 40, 60) flags_atom = FPRINT|OPENCONTAINER volume = 60 attack_speed = 4 + var/randomize = TRUE /obj/item/reagent_container/glass/bottle/on_reagent_change() update_icon() @@ -29,247 +30,224 @@ /obj/item/reagent_container/glass/bottle/Initialize() . = ..() - if(!icon_state) + if(randomize) icon_state = "bottle-[rand(1,4)]" /obj/item/reagent_container/glass/bottle/update_icon() overlays.Cut() - if(reagents.total_volume && (icon_state == "bottle-1" || icon_state == "bottle-2" || icon_state == "bottle-3" || icon_state == "bottle-4")) + if(reagents.total_volume) var/image/filling = image('icons/obj/items/reagentfillings.dmi', src, "[icon_state]10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) - if(0 to 9) filling.icon_state = "[icon_state]--10" - if(10 to 24) filling.icon_state = "[icon_state]-10" - if(25 to 49) filling.icon_state = "[icon_state]-25" - if(50 to 74) filling.icon_state = "[icon_state]-50" - if(75 to 79) filling.icon_state = "[icon_state]-75" - if(80 to 90) filling.icon_state = "[icon_state]-80" - if(91 to INFINITY) filling.icon_state = "[icon_state]-100" + if(0) filling.icon_state = null + if(1 to 20) filling.icon_state = "[icon_state]-20" + if(21 to 40) filling.icon_state = "[icon_state]-40" + if(41 to 60) filling.icon_state = "[icon_state]-60" + if(61 to 80) filling.icon_state = "[icon_state]-80" + if(81 to INFINITY) filling.icon_state = "[icon_state]-100" filling.color = mix_color_from_reagents(reagents.reagent_list) overlays += filling - if (!is_open_container()) - var/image/lid = image(icon, src, "lid_bottle") + if(!is_open_container()) + var/image/lid = image(icon, src, "lid_[icon_state]") overlays += lid + /obj/item/reagent_container/glass/bottle/inaprovaline name = "\improper Inaprovaline bottle" desc = "A small bottle. Contains inaprovaline - used to stabilize patients." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle19" amount_per_transfer_from_this = 60 /obj/item/reagent_container/glass/bottle/inaprovaline/Initialize() . = ..() reagents.add_reagent("inaprovaline", 60) + update_icon() /obj/item/reagent_container/glass/bottle/kelotane name = "\improper Kelotane bottle" desc = "A small bottle. Contains kelotane - used to treat burned areas." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle16" amount_per_transfer_from_this = 60 /obj/item/reagent_container/glass/bottle/kelotane/Initialize() . = ..() reagents.add_reagent("kelotane", 60) + update_icon() /obj/item/reagent_container/glass/bottle/dexalin name = "\improper Dexalin bottle" - desc = "A small bottle. Contains dexalin - used to treat oxygen deprivation." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle10" amount_per_transfer_from_this = 60 /obj/item/reagent_container/glass/bottle/dexalin/Initialize() . = ..() reagents.add_reagent("dexalin", 60) + update_icon() /obj/item/reagent_container/glass/bottle/spaceacillin name = "\improper Spaceacillin bottle" desc = "A small bottle. Contains spaceacillin - used to treat infected wounds." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle8" amount_per_transfer_from_this = 60 /obj/item/reagent_container/glass/bottle/spaceacillin/Initialize() . = ..() reagents.add_reagent("spaceacillin", 60) + update_icon() /obj/item/reagent_container/glass/bottle/toxin name = "toxin bottle" desc = "A small bottle of toxins. Do not drink, it is poisonous." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle12" - /obj/item/reagent_container/glass/bottle/toxin/Initialize() . = ..() reagents.add_reagent("toxin", 60) + update_icon() /obj/item/reagent_container/glass/bottle/cyanide name = "cyanide bottle" desc = "A small bottle of cyanide. Bitter almonds?" - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle12" /obj/item/reagent_container/glass/bottle/cyanide/Initialize() . = ..() reagents.add_reagent("cyanide", 60) + update_icon() /obj/item/reagent_container/glass/bottle/stoxin name = "Soporific bottle" desc = "A small bottle of soporific. Just the fumes make you sleepy." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle20" amount_per_transfer_from_this = 60 /obj/item/reagent_container/glass/bottle/stoxin/Initialize() . = ..() reagents.add_reagent("stoxin", 60) + update_icon() /obj/item/reagent_container/glass/bottle/chloralhydrate name = "chloral hydrate bottle" desc = "A small bottle of Choral Hydrate. Mickey's Favorite!" - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle20" /obj/item/reagent_container/glass/bottle/chloralhydrate/Initialize() . = ..() reagents.add_reagent("chloralhydrate", 30) //Intentionally low since it is so strong. Still enough to knock someone out. + update_icon() /obj/item/reagent_container/glass/bottle/antitoxin name = "\improper Dylovene bottle" desc = "A small bottle of dylovene. Counters poisons, and repairs toxin damage. A wonder drug." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle7" amount_per_transfer_from_this = 60 /obj/item/reagent_container/glass/bottle/antitoxin/Initialize() . = ..() reagents.add_reagent("anti_toxin", 60) + update_icon() /obj/item/reagent_container/glass/bottle/mutagen name = "unstable mutagen bottle" desc = "A small bottle of unstable mutagen. Randomly changes the DNA structure of whoever comes in contact." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle7" /obj/item/reagent_container/glass/bottle/mutagen/Initialize() . = ..() reagents.add_reagent("mutagen", 60) + update_icon() /obj/item/reagent_container/glass/bottle/ammonia name = "ammonia bottle" desc = "A small bottle." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle20" /obj/item/reagent_container/glass/bottle/ammonia/Initialize() . = ..() reagents.add_reagent("ammonia", 60) + update_icon() /obj/item/reagent_container/glass/bottle/diethylamine name = "diethylamine bottle" desc = "A small bottle. Contains a potent fertiliser." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle17" /obj/item/reagent_container/glass/bottle/diethylamine/Initialize() . = ..() reagents.add_reagent("diethylamine", 60) + update_icon() /obj/item/reagent_container/glass/bottle/flu_virion name = "flu virion culture bottle" desc = "A small bottle. Contains H13N1 flu virion culture in synthblood medium." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/flu_virion/Initialize() . = ..() var/datum/disease/F = new /datum/disease/advance/flu(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/reagent_container/glass/bottle/epiglottis_virion name = "epiglottis virion culture bottle" desc = "A small bottle. Contains Epiglottis virion culture in synthblood medium." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/epiglottis_virion/Initialize() . = ..() var/datum/disease/F = new /datum/disease/advance/voice_change(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/reagent_container/glass/bottle/liver_enhance_virion name = "liver enhancement virion culture bottle" desc = "A small bottle. Contains liver enhancement virion culture in synthblood medium." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/liver_enhance_virion/Initialize() . = ..() var/datum/disease/F = new /datum/disease/advance/heal(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/reagent_container/glass/bottle/hullucigen_virion name = "hullucigen virion culture bottle" desc = "A small bottle. Contains hullucigen virion culture in synthblood medium." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/hullucigen_virion/Initialize() . = ..() var/datum/disease/F = new /datum/disease/advance/hullucigen(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/reagent_container/glass/bottle/pierrot_throat name = "\improper Pierrot's Throat culture bottle" desc = "A small bottle. Contains H0NI<42 virion culture in synthblood medium." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/pierrot_throat/Initialize() . = ..() var/datum/disease/F = new /datum/disease/pierrot_throat(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/reagent_container/glass/bottle/cold name = "rhinovirus culture bottle" desc = "A small bottle. Contains XY-rhinovirus culture in synthblood medium." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/cold/Initialize() . = ..() var/datum/disease/advance/F = new /datum/disease/advance/cold(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/reagent_container/glass/bottle/random name = "random culture bottle" desc = "A small bottle. Contains a random disease." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/random/Initialize() . = ..() var/datum/disease/advance/F = new(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/reagent_container/glass/bottle/gbs name = "\improper GBS culture bottle" desc = "A small bottle. Contains Gravitokinetic Bipotential SADS+ culture in synthblood medium."//Or simply - General BullShit - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" amount_per_transfer_from_this = 5 /obj/item/reagent_container/glass/bottle/gbs/Initialize() @@ -278,24 +256,23 @@ var/datum/disease/F = new /datum/disease/gbs var/list/data = list("virus"= F) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/reagent_container/glass/bottle/fake_gbs name = "\improper GBS culture bottle" desc = "A small bottle. Contains Gravitokinetic Bipotential SADS- culture in synthblood medium."//Or simply - General BullShit - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/fake_gbs/Initialize() . = ..() var/datum/disease/F = new /datum/disease/fake_gbs(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() + /* /obj/item/reagent_container/glass/bottle/rhumba_beat name = "Rhumba Beat culture bottle" desc = "A small bottle. Contains The Rhumba Beat culture in synthblood medium."//Or simply - General BullShit - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" amount_per_transfer_from_this = 5 New() @@ -305,126 +282,117 @@ var/datum/disease/F = new /datum/disease/rhumba_beat var/list/data = list("virus"= F) R.add_reagent("blood", 20, data) + update_icon() + */ /obj/item/reagent_container/glass/bottle/brainrot name = "\improper Brainrot culture bottle" desc = "A small bottle. Contains Cryptococcus Cosmosis culture in synthblood medium." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/brainrot/Initialize() . = ..() var/datum/disease/F = new /datum/disease/brainrot(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/reagent_container/glass/bottle/magnitis name = "\improper Magnitis culture bottle" desc = "A small bottle. Contains a small dosage of Fukkos Miracos." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/magnitis/Initialize() . = ..() var/datum/disease/F = new /datum/disease/magnitis(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/reagent_container/glass/bottle/pacid name = "polytrinic acid bottle" desc = "A small bottle. Contains a small amount of Polytrinic Acid, an extremely potent and dangerous acid." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle17" /obj/item/reagent_container/glass/bottle/pacid/Initialize() . = ..() reagents.add_reagent("pacid", 60) + update_icon() /obj/item/reagent_container/glass/bottle/adminordrazine name = "\improper Adminordrazine bottle" desc = "A small bottle. Contains the liquid essence of the gods." - icon = 'icons/obj/items/drinks.dmi' - icon_state = "holyflask" /obj/item/reagent_container/glass/bottle/adminordrazine/Initialize() . = ..() reagents.add_reagent("adminordrazine", 60) + update_icon() /obj/item/reagent_container/glass/bottle/capsaicin name = "\improper Capsaicin bottle" desc = "A small bottle. Contains hot sauce." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle3" /obj/item/reagent_container/glass/bottle/capsaicin/Initialize() . = ..() reagents.add_reagent("capsaicin", 60) + update_icon() /obj/item/reagent_container/glass/bottle/frostoil name = "\improper Frost Oil bottle" desc = "A small bottle. Contains cold sauce." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle17" /obj/item/reagent_container/glass/bottle/frostoil/Initialize() . = ..() reagents.add_reagent("frostoil", 60) + update_icon() /obj/item/reagent_container/glass/bottle/bicaridine name = "\improper Bicaridine bottle" desc = "A small bottle. Contains Bicaridine - Used to treat brute damage." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle17" amount_per_transfer_from_this = 60 /obj/item/reagent_container/glass/bottle/bicaridine/Initialize() . = ..() reagents.add_reagent("bicaridine", 60) + update_icon() /obj/item/reagent_container/glass/bottle/peridaxon name = "\improper Peridaxon bottle" desc = "A small bottle. Contains Peridaxon - Used by lazy doctors to temporarily halt the effects of internal organ damage." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle4" volume = 60 amount_per_transfer_from_this = 60 /obj/item/reagent_container/glass/bottle/peridaxon/Initialize() . = ..() reagents.add_reagent("peridaxon", 60) + update_icon() /obj/item/reagent_container/glass/bottle/tramadol name = "\improper Tramadol bottle" desc = "A small bottle. Contains Tramadol - Used as a basic painkiller." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle1" volume = 60 amount_per_transfer_from_this = 60 /obj/item/reagent_container/glass/bottle/tramadol/Initialize() . = ..() reagents.add_reagent("tramadol", 60) + update_icon() /obj/item/reagent_container/glass/bottle/oxycodone name = "\improper Oxycodone bottle" desc = "A small bottle. Contains Oxycodone - Used as an Extreme Painkiller. ILLEGAL TO DISTRIBUTE." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle2" volume = 60 amount_per_transfer_from_this = 60 /obj/item/reagent_container/glass/bottle/oxycodone/Initialize() . = ..() reagents.add_reagent("oxycodone", 60) + update_icon() /obj/item/reagent_container/glass/bottle/tricordrazine name = "\improper Tricordrazine bottle" desc = "A small bottle. Contains tricordrazine - A weak but catch-all medicine for treating all sorts of damage." - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle18" volume = 60 /obj/item/reagent_container/glass/bottle/tricordrazine/Initialize() . = ..() reagents.add_reagent("tricordrazine", 60) + update_icon() diff --git a/code/game/objects/items/reagent_containers/glass/bottle/robot.dm b/code/game/objects/items/reagent_containers/glass/bottle/robot.dm index 553b3e0dcbc3..67c397e30eb5 100644 --- a/code/game/objects/items/reagent_containers/glass/bottle/robot.dm +++ b/code/game/objects/items/reagent_containers/glass/bottle/robot.dm @@ -10,7 +10,6 @@ name = "internal inaprovaline bottle" desc = "A small bottle. Contains inaprovaline - used to stabilize patients." icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle16" reagent = "inaprovaline" /obj/item/reagent_container/glass/bottle/robot/inaprovaline/Initialize() @@ -23,7 +22,6 @@ name = "internal anti-toxin bottle" desc = "A small bottle of Anti-toxins. Counters poisons, and repairs damage, a wonder drug." icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle17" reagent = "anti_toxin" /obj/item/reagent_container/glass/bottle/robot/antitoxin/Initialize() diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index cb5071326e13..d984f01ae1be 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -107,7 +107,7 @@ GLOBAL_LIST_INIT_TYPED(plasteel_recipes, /datum/stack_recipe, list ( \ /obj/item/stack/sheet/plasteel name = "plasteel sheet" singular_name = "plasteel sheet" - desc = "These sheets are an alloy of iron and phoron." + desc = "Plasteel is an expensive, durable material made from combining platinum, steel, and advanced polymers to create a metal that is corrosion-resistant, highly durable, and lightweight. The only reason this isn't used more often is because of how damn costly it is." icon_state = "sheet-plasteel" item_state = "sheet-plasteel" matter = list("metal" = 3750) diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index 3b2dbfa33aa4..3e7c00f3d0ff 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -123,7 +123,6 @@ desc = "It's an emergency medical kit containing lifesaving anti-toxic medication. With medical training you can fit this in a backpack." icon_state = "antitoxin" item_state = "firstaid-toxin" - possible_icons_full = list("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") /obj/item/storage/firstaid/toxin/fill_preset_inventory() new /obj/item/device/healthanalyzer(src) diff --git a/code/game/objects/items/tools/hydro_tools.dm b/code/game/objects/items/tools/hydro_tools.dm index 7ae4989104f6..045a5b864555 100644 --- a/code/game/objects/items/tools/hydro_tools.dm +++ b/code/game/objects/items/tools/hydro_tools.dm @@ -31,24 +31,19 @@ /obj/item/tool/plantspray/pests/old name = "bottle of pestkiller" - icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle16" /obj/item/tool/plantspray/pests/old/carbaryl name = "bottle of carbaryl" - icon_state = "bottle16" toxicity = 4 pest_kill_str = 2 /obj/item/tool/plantspray/pests/old/lindane name = "bottle of lindane" - icon_state = "bottle18" toxicity = 6 pest_kill_str = 4 /obj/item/tool/plantspray/pests/old/phosmet name = "bottle of phosmet" - icon_state = "bottle15" toxicity = 8 pest_kill_str = 7 @@ -57,25 +52,21 @@ /obj/item/tool/weedkiller name = "bottle of weedkiller" icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle16" var/toxicity = 0 var/weed_kill_str = 0 /obj/item/tool/weedkiller/triclopyr name = "bottle of glyphosate" - icon_state = "bottle16" toxicity = 4 weed_kill_str = 2 /obj/item/tool/weedkiller/lindane name = "bottle of triclopyr" - icon_state = "bottle18" toxicity = 6 weed_kill_str = 4 /obj/item/tool/weedkiller/D24 name = "bottle of 2,4-D" - icon_state = "bottle15" toxicity = 8 weed_kill_str = 7 diff --git a/code/game/objects/structures/crates_lockers/closets/coffin.dm b/code/game/objects/structures/crates_lockers/closets/coffin.dm index 41c27ae47519..c1c0839fa6f5 100644 --- a/code/game/objects/structures/crates_lockers/closets/coffin.dm +++ b/code/game/objects/structures/crates_lockers/closets/coffin.dm @@ -14,6 +14,13 @@ else icon_state = icon_opened +/obj/structure/closet/coffin/uscm + name = "\improper USCM coffin" + desc = "A burial receptacle for dearly departed Marines, adorned in red and finished with the Corps' emblem on the interior. Semper fi." + icon_state = "uscm_coffin" + icon_closed = "uscm_coffin" + icon_opened = "uscm_coffin_open" + /obj/structure/closet/coffin/predator name = "strange coffin" desc = "It's a burial receptacle for the dearly departed. Seems to have weird markings on the side..?" 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" diff --git a/code/modules/clothing/under/ties.dm b/code/modules/clothing/under/ties.dm index 767ff51438dd..4fe8cc193ce6 100644 --- a/code/modules/clothing/under/ties.dm +++ b/code/modules/clothing/under/ties.dm @@ -154,18 +154,18 @@ /obj/item/clothing/accessory/medal/on_attached(obj/item/clothing/S, mob/living/user, silent) . = ..() if(.) - RegisterSignal(S, COMSIG_ITEM_PICKUP, PROC_REF(remove_medal)) + RegisterSignal(S, COMSIG_ITEM_EQUIPPED, PROC_REF(remove_medal)) -/obj/item/clothing/accessory/medal/proc/remove_medal(obj/item/clothing/C, mob/user) +/obj/item/clothing/accessory/medal/proc/remove_medal(obj/item/clothing/C, mob/user, slot) SIGNAL_HANDLER - if(user.real_name != recipient_name) + if(user.real_name != recipient_name && (slot == WEAR_BODY || slot == WEAR_JACKET)) C.remove_accessory(user, src) user.drop_held_item(src) /obj/item/clothing/accessory/medal/on_removed(mob/living/user, obj/item/clothing/C) . = ..() if(.) - UnregisterSignal(C, COMSIG_ITEM_PICKUP) + UnregisterSignal(C, COMSIG_ITEM_EQUIPPED) /obj/item/clothing/accessory/medal/attack(mob/living/carbon/human/H, mob/living/carbon/human/user) if(!(istype(H) && istype(user))) diff --git a/code/modules/gear_presets/_select_equipment.dm b/code/modules/gear_presets/_select_equipment.dm index 92c5e5549611..5311a7a79a3b 100644 --- a/code/modules/gear_presets/_select_equipment.dm +++ b/code/modules/gear_presets/_select_equipment.dm @@ -201,7 +201,7 @@ qdel(R) if(flags & EQUIPMENT_PRESET_MARINE) - var/playtime = get_job_playtime(new_human.client, assignment) + var/playtime = get_job_playtime(new_human.client, rank) var/medal_type switch(playtime) @@ -220,7 +220,7 @@ if(medal_type) var/obj/item/clothing/accessory/medal/medal = new medal_type() medal.recipient_name = new_human.real_name - medal.recipient_rank = current_rank + medal.recipient_rank = assignment if(new_human.wear_suit && new_human.wear_suit.can_attach_accessory(medal)) new_human.wear_suit.attach_accessory(new_human, medal, TRUE) diff --git a/code/modules/hydroponics/hydro_tools.dm b/code/modules/hydroponics/hydro_tools.dm index eb0d54ce91bb..3603448a4f4f 100644 --- a/code/modules/hydroponics/hydro_tools.dm +++ b/code/modules/hydroponics/hydro_tools.dm @@ -157,7 +157,7 @@ name = "fertilizer bottle" desc = "A small glass bottle. Can hold up to 10 units." icon = 'icons/obj/items/chemistry.dmi' - icon_state = "bottle16" + icon_state = "fertilizer" flags_atom = FPRINT| OPENCONTAINER possible_transfer_amounts = null w_class = SIZE_SMALL @@ -179,15 +179,12 @@ /obj/item/reagent_container/glass/fertilizer/ez name = "bottle of E-Z-Nutrient" - icon_state = "bottle16" fertilizer = "eznutrient" /obj/item/reagent_container/glass/fertilizer/l4z name = "bottle of Left 4 Zed" - icon_state = "bottle18" fertilizer = "left4zed" /obj/item/reagent_container/glass/fertilizer/rh name = "bottle of Robust Harvest" - icon_state = "bottle15" fertilizer = "robustharvest" diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index dd0327e3821d..76550fbe079b 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -190,8 +190,9 @@ GLOBAL_LIST_INIT(apc_wire_descriptions, list( ui.open() /obj/structure/machinery/power/apc/ui_status(mob/user) - if(!opened && can_use(user, 1)) - . = UI_INTERACTIVE + . = ..() + if(opened || !can_use(user, TRUE)) + return UI_DISABLED /obj/structure/machinery/power/apc/ui_state(mob/user) return GLOB.not_incapacitated_and_adjacent_state diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index c9863d3ee9cd..46d9374cb832 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -281,14 +281,13 @@ // TGUI STUFF \\ /obj/structure/machinery/power/smes/ui_status(mob/user) - if(!(stat & BROKEN) && !open_hatch) - . = UI_INTERACTIVE - -/obj/structure/machinery/power/smes/ui_state(mob/user) + . = ..() if(stat & BROKEN) return UI_CLOSE if(open_hatch) return UI_DISABLED + +/obj/structure/machinery/power/smes/ui_state(mob/user) return GLOB.not_incapacitated_and_adjacent_state /obj/structure/machinery/power/smes/tgui_interact(mob/user, datum/tgui/ui) diff --git a/code/modules/reagents/chemistry_machinery/pandemic.dm b/code/modules/reagents/chemistry_machinery/pandemic.dm index 5cd7f6584705..f44da3af9613 100644 --- a/code/modules/reagents/chemistry_machinery/pandemic.dm +++ b/code/modules/reagents/chemistry_machinery/pandemic.dm @@ -87,7 +87,6 @@ if(!(virus_type in discovered_diseases)) return var/obj/item/reagent_container/glass/bottle/B = new/obj/item/reagent_container/glass/bottle(src.loc) - B.icon_state = "bottle3" var/datum/disease/D = null if(!virus_type) var/datum/disease/advance/A = GLOB.archive_diseases[href_list["create_virus_culture"]] diff --git a/code/modules/reagents/chemistry_reagents/medical.dm b/code/modules/reagents/chemistry_reagents/medical.dm index f69d1b952c43..1e9eb0e0084b 100644 --- a/code/modules/reagents/chemistry_reagents/medical.dm +++ b/code/modules/reagents/chemistry_reagents/medical.dm @@ -8,7 +8,7 @@ id = "inaprovaline" description = "Inaprovaline is a synaptic stimulant and cardiostimulant. Commonly used to stabilize patients. If the lungs are functional, inaprovaline will allow respiration while under cardiac arrest. Slows down bleeding and acts as a weak painkiller. Overdosing may cause severe damage to cardiac tissue." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#dcbaf0" // rgb: 200, 165, 220 overdose = HIGH_REAGENTS_OVERDOSE overdose_critical = HIGH_REAGENTS_OVERDOSE_CRITICAL chemclass = CHEM_CLASS_COMMON @@ -42,7 +42,7 @@ id = "tramadol" description = "Tramadol is a centrally acting analgesic and is considered to be a relatively safe. The analgesic potency is claimed to be about one tenth that of morphine. It is used to treat both acute and chronic pain of moderate to (moderately) severe intensity. Tramadol is generally considered as a medicinal drug with a low potential for dependence relative to morphine. Overdosing on tramadol is highly toxic." reagent_state = LIQUID - color = "#C8A5DC" + color = "#d7c7e0" custom_metabolism = AMOUNT_PER_TIME(15, 10 MINUTES) // Lasts 10 minutes for 15 units overdose = REAGENTS_OVERDOSE overdose_critical = REAGENTS_OVERDOSE_CRITICAL @@ -54,7 +54,7 @@ id = "oxycodone" description = "Oxycodone is an opioid agonist with addiction potential similar to that of morphine. It is approved for the treatment of patients with moderate to severe pain who are expected to need continuous opioids for an extended period of time. Overdosing on oxycodone can cause hallucinations, brain damage and be highly toxic." reagent_state = LIQUID - color = "#E01D25" + color = "#1cc282" custom_metabolism = AMOUNT_PER_TIME(15, 5 MINUTES) // Lasts 5 minutes for 15 units overdose = MED_REAGENTS_OVERDOSE overdose_critical = MED_REAGENTS_OVERDOSE_CRITICAL @@ -66,7 +66,7 @@ id = "sterilizine" description = "A sterilizer used to clean wounds in preparation for surgery. Its use has mostly been outclassed to the cheaper alternative of space cleaner." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#b8d2f5" // rgb: 200, 165, 220 chemclass = CHEM_CLASS_UNCOMMON /datum/reagent/medical/leporazine @@ -74,7 +74,7 @@ id = "leporazine" description = "A drug used to treat hypothermia and hyperthermia. Stabilizes patient body temperture. Prevents the use of cryogenics. Overdosing on leporazine can cause extreme drowsyness." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#a03919" // rgb: 200, 165, 220 overdose = REAGENTS_OVERDOSE overdose_critical = REAGENTS_OVERDOSE_CRITICAL chemclass = CHEM_CLASS_UNCOMMON @@ -85,7 +85,7 @@ id = "kelotane" description = "Common medicine used to treat burns, caustic and corrosive trauma. Overdosing on kelotane can cause internal tissue damage." reagent_state = LIQUID - color = "#D8C58C" + color = "#d8b343" overdose = REAGENTS_OVERDOSE overdose_critical = REAGENTS_OVERDOSE_CRITICAL chemclass = CHEM_CLASS_COMMON @@ -96,7 +96,7 @@ id = "dermaline" description = "Advanced medicine used to treat severe burn trauma. Enables the body to restore even the direst heat-damaged tissue. Overdosing on dermaline can cause severe internal tissue damage." reagent_state = LIQUID - color = "#F8C57C" + color = "#e2972e" overdose = LOWH_REAGENTS_OVERDOSE overdose_critical = LOWH_REAGENTS_OVERDOSE_CRITICAL chemclass = CHEM_CLASS_UNCOMMON @@ -107,7 +107,7 @@ id = "dexalin" description = "Dexalin is used in the treatment of oxygen deprivation by feeding oxygen to red blood cells directly inside the bloodstream. Used as an antidote to lexorin poisoning." reagent_state = LIQUID - color = "#C865FC" + color = "#1f28a7" overdose = REAGENTS_OVERDOSE overdose_critical = REAGENTS_OVERDOSE_CRITICAL chemclass = CHEM_CLASS_COMMON @@ -118,7 +118,7 @@ id = "dexalinp" description = "Dexalin Plus is an upgraded form of Dexalin with added iron and carbon to quicken the rate which oxygen binds to the hemoglobin in red blood cells." reagent_state = LIQUID - color = "#C8A5FC" + color = "#293fff" overdose = LOWH_REAGENTS_OVERDOSE overdose_critical = LOWH_REAGENTS_OVERDOSE_CRITICAL chemclass = CHEM_CLASS_UNCOMMON @@ -129,7 +129,7 @@ id = "tricordrazine" description = "Tricordrazine is a highly potent stimulant, originally derived from cordrazine. Can be used to treat a wide range of injuries." reagent_state = LIQUID - color = "#B865CC" + color = "#d87f2b" overdose = REAGENTS_OVERDOSE overdose_critical = REAGENTS_OVERDOSE_CRITICAL chemclass = CHEM_CLASS_UNCOMMON @@ -140,7 +140,7 @@ id = "anti_toxin" description = "General use anti-toxin, that neutralizes most toxins in the bloodstream. Commonly used in many advanced chemicals. Can be used as a mild anti-hallucinogen and to reduce tiredness." reagent_state = LIQUID - color = "#A8F59C" + color = "#3fc92a" overdose = REAGENTS_OVERDOSE overdose_critical = REAGENTS_OVERDOSE_CRITICAL chemclass = CHEM_CLASS_COMMON @@ -151,7 +151,7 @@ id = "adminordrazine" description = "A magical substance created by gods to dissolve extreme amounts of salt." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#dae63b" // rgb: 200, 165, 220 properties = list(PROPERTY_OMNIPOTENT = 2) flags = REAGENT_TYPE_MEDICAL @@ -160,7 +160,7 @@ id = "thwei" description = "A strange, alien liquid." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#41c498" // rgb: 200, 165, 220 chemclass = CHEM_CLASS_SPECIAL objective_value = OBJECTIVE_HIGH_VALUE properties = list( @@ -182,7 +182,7 @@ id = "neuraline" description = "A chemical cocktail tailored to enhance or dampen specific neural processes." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#a244d8" // rgb: 200, 165, 220 custom_metabolism = AMOUNT_PER_TIME(1, 5 SECONDS) overdose = 2 overdose_critical = 3 @@ -195,7 +195,7 @@ id = "arithrazine" description = "A stabilized variant of dylovene. Its toxin-cleansing properties are weakened and there are harmful side effects, but it does not react with other compounds to create toxin." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#3c8529" // rgb: 200, 165, 220 custom_metabolism = AMOUNT_PER_TIME(1, 40 SECONDS) overdose = REAGENTS_OVERDOSE/2 overdose_critical = REAGENTS_OVERDOSE_CRITICAL/2 @@ -207,7 +207,7 @@ id = "russianred" description = "An emergency radiation treatment. The list of potential side effects include retinal damage and unconsciousness." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#ce2727" // rgb: 200, 165, 220 custom_metabolism = AMOUNT_PER_TIME(1, 2 SECONDS) overdose = MED_REAGENTS_OVERDOSE overdose_critical = MED_REAGENTS_OVERDOSE_CRITICAL @@ -218,7 +218,7 @@ id = "alkysine" description = "Alkysine is a drug used to lessen and heal the damage to neurological tissue after a catastrophic injury. Small amounts can repair extensive brain trauma. Functions as a very weak painkiller. Overdosing on alkysine is extremely toxic." reagent_state = LIQUID - color = "#E89599" + color = "#e9d191" custom_metabolism = AMOUNT_PER_TIME(1, 40 SECONDS) overdose = REAGENTS_OVERDOSE overdose_critical = REAGENTS_OVERDOSE_CRITICAL @@ -241,7 +241,7 @@ id = "peridaxon" description = "Prevents symptoms caused by damaged internal organs while in the bloodstream, but does not fix the organ damage. Recommended for patients awaiting internal organ surgery. Overdosing on peridaxon will cause internal tissue damage." reagent_state = LIQUID - color = "#C845DC" + color = "#403142" overdose = LOWH_REAGENTS_OVERDOSE overdose_critical = LOWH_REAGENTS_OVERDOSE_CRITICAL custom_metabolism = AMOUNT_PER_TIME(1, 40 SECONDS) @@ -253,7 +253,7 @@ id = "bicaridine" description = "Bicaridine is an analgesic medication and can be used to treat severe external blunt trauma and to stabilize patients. Overdosing on Bicaridine will cause caustic burns and toxins." reagent_state = LIQUID - color = "#E8756C" + color = "#e7554a" overdose = REAGENTS_OVERDOSE overdose_critical = REAGENTS_OVERDOSE_CRITICAL chemclass = CHEM_CLASS_COMMON @@ -288,7 +288,7 @@ id = "ultrazine" description = "A highly-potent, long-lasting combination CNS and muscle stimulant. Extremely addictive." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#ffec43" // rgb: 200, 165, 220 custom_metabolism = 0.0167 //5 units will last approximately 10 minutes overdose = LOWM_REAGENTS_OVERDOSE overdose_critical = LOWM_REAGENTS_OVERDOSE_CRITICAL @@ -314,7 +314,7 @@ id = "cryoxadone" description = "Industrial grade cryogenic medicine. Treats most types of tissue damage. Its main limitation is that the patient's body temperature must be under 170K to metabolise correctly." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#4acaca" // rgb: 200, 165, 220 chemclass = CHEM_CLASS_UNCOMMON properties = list(PROPERTY_CRYOMETABOLIZING = 2, PROPERTY_NEOGENETIC = 1, PROPERTY_ANTICORROSIVE = 1, PROPERTY_ANTITOXIC = 1, PROPERTY_ANTICARCINOGENIC = 1) @@ -332,7 +332,7 @@ id = "clonexadone" description = "Advanced cryogenic medicine made from cryoxadone. Treats most types of tissue damage. Requires temperatures below 170K to to metabolise correctly." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#51b4db" // rgb: 200, 165, 220 chemclass = CHEM_CLASS_UNCOMMON properties = list(PROPERTY_CRYOMETABOLIZING = 6, PROPERTY_NEOGENETIC = 3, PROPERTY_ANTICORROSIVE = 3, PROPERTY_ANTITOXIC = 3, PROPERTY_ANTICARCINOGENIC = 3) @@ -351,7 +351,7 @@ id = "spaceacillin" description = "General use theta-lactam antibiotic. Prevents and cures mundane infections." reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 + color = "#9749c4" // rgb: 200, 165, 220 custom_metabolism = AMOUNT_PER_TIME(1, 200 SECONDS) overdose = REAGENTS_OVERDOSE overdose_critical = REAGENTS_OVERDOSE_CRITICAL diff --git a/html/changelogs/AutoChangeLog-pr-5898.yml b/html/changelogs/AutoChangeLog-pr-5898.yml deleted file mode 100644 index 6192f2e61d85..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5898.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Segrain" -delete-after: True -changes: - - bugfix: "Wiping frequencies off radiotowers no longer breaks them forever." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5900.yml b/html/changelogs/AutoChangeLog-pr-5900.yml deleted file mode 100644 index d2e2212646e2..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5900.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Segrain" -delete-after: True -changes: - - rscadd: "Requisitions' vendor now has medical radio keys in stock." - - rscadd: "CE and CMO can now get spare departmental headsets from their vendors to recruit survivors without having to go to Requisitions." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5902.yml b/html/changelogs/AutoChangeLog-pr-5902.yml deleted file mode 100644 index 090030cec56a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5902.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Stakeyng" -delete-after: True -changes: - - balance: "Drop pouch has more space (2 large (unchanged), 4 medium, 8 small)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5904.yml b/html/changelogs/AutoChangeLog-pr-5904.yml deleted file mode 100644 index 2b0302639478..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5904.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Katskan" -delete-after: True -changes: - - balance: "Medical Skill 4 reduced speed buff from -75% duration to -50% duration" - - balance: "Medical Skill 3 increased speed buff from -0% duration to -25% duration" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5911.yml b/html/changelogs/AutoChangeLog-pr-5911.yml deleted file mode 100644 index be5faf7a6811..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5911.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - bugfix: "Fix chestrig not displaying on maps with different skins (e.g. Shivas)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5917.yml b/html/changelogs/AutoChangeLog-pr-5917.yml deleted file mode 100644 index 1e901448a212..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5917.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "ihatethisengine2" -delete-after: True -changes: - - bugfix: "Dropship door prying can now always be performed by queen even if open or not locked" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5932.yml b/html/changelogs/AutoChangeLog-pr-5932.yml new file mode 100644 index 000000000000..e7584e57568b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5932.yml @@ -0,0 +1,4 @@ +author: "nauticall" +delete-after: True +changes: + - bugfix: "Makes pill bottle caps appear on closed pill bottles again." \ No newline at end of file diff --git a/html/changelogs/archive/2024-03.yml b/html/changelogs/archive/2024-03.yml index df09e0a90a35..62e6449f15b3 100644 --- a/html/changelogs/archive/2024-03.yml +++ b/html/changelogs/archive/2024-03.yml @@ -121,3 +121,62 @@ Segrain: - admin: Actually fixed the last case of being warned against interacting with ticket already marked by you. +2024-03-12: + Drathek: + - bugfix: Fix chestrig not displaying on maps with different skins (e.g. Shivas) + Katskan: + - balance: Medical Skill 4 reduced speed buff from -75% duration to -50% duration + - balance: Medical Skill 3 increased speed buff from -0% duration to -25% duration + Segrain: + - rscadd: Requisitions' vendor now has medical radio keys in stock. + - rscadd: CE and CMO can now get spare departmental headsets from their vendors + to recruit survivors without having to go to Requisitions. + - bugfix: Wiping frequencies off radiotowers no longer breaks them forever. + Stakeyng: + - balance: Drop pouch has more space (2 large (unchanged), 4 medium, 8 small) + ihatethisengine2: + - bugfix: Dropship door prying can now always be performed by queen even if open + or not locked + realforest2001: + - soundadd: Added pda_ping.ogg, sourced from Paradise SS13 mailapproved.ogg + - rscadd: Added notification sounds from certain APOLLO ticket interactions. + - rscadd: People making an access ticket request are now notified of the status + changes. +2024-03-13: + Segrain: + - bugfix: Picking up clothes/armour with somebody else's medal attached no longer + makes the medal fall off (trying to wear them still does). + - 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. +2024-03-15: + Drathek: + - balance: The light replacer can now be used to skip the crowbar, welding, and + wire steps when repairing colony lights. + - bugfix: Fixes SMES and APC interfaces not checking adjacency or incapacitated + states + - spellcheck: Fixed examine text for colony lights (improper names and not powered + text) + Huffie56: + - 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. + - 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. + Segrain: + - qol: Middleclicking beds/chairs/etc is now a shortcut for buckling to them. diff --git a/icons/effects/spacevines.dmi b/icons/effects/spacevines.dmi index 5f6f19fdd916..bcd121055bf5 100644 Binary files a/icons/effects/spacevines.dmi and b/icons/effects/spacevines.dmi differ diff --git a/icons/mob/hud/hud.dmi b/icons/mob/hud/hud.dmi index c9e4c0c6c23d..507ec0dd485b 100644 Binary files a/icons/mob/hud/hud.dmi and b/icons/mob/hud/hud.dmi differ diff --git a/icons/obj/items/chemistry.dmi b/icons/obj/items/chemistry.dmi index 1eaef75bb6fb..e540af809714 100644 Binary files a/icons/obj/items/chemistry.dmi and b/icons/obj/items/chemistry.dmi differ diff --git a/icons/obj/items/items.dmi b/icons/obj/items/items.dmi index 58f267721345..bf9b64474af5 100644 Binary files a/icons/obj/items/items.dmi and b/icons/obj/items/items.dmi differ diff --git a/icons/obj/items/reagentfillings.dmi b/icons/obj/items/reagentfillings.dmi index 1514db495e13..4bfd2752482b 100644 Binary files a/icons/obj/items/reagentfillings.dmi and b/icons/obj/items/reagentfillings.dmi differ diff --git a/icons/obj/items/storage.dmi b/icons/obj/items/storage.dmi index ed78543439a0..44dfac1c246e 100644 Binary files a/icons/obj/items/storage.dmi and b/icons/obj/items/storage.dmi differ diff --git a/icons/obj/structures/closet.dmi b/icons/obj/structures/closet.dmi index ebac1789024f..4377a48779cb 100644 Binary files a/icons/obj/structures/closet.dmi and b/icons/obj/structures/closet.dmi differ diff --git a/icons/obj/structures/machinery/big_floodlight.dmi b/icons/obj/structures/machinery/big_floodlight.dmi index b76f63956a2c..3e180d9a620e 100644 Binary files a/icons/obj/structures/machinery/big_floodlight.dmi and b/icons/obj/structures/machinery/big_floodlight.dmi differ diff --git a/icons/obj/structures/mortar.dmi b/icons/obj/structures/mortar.dmi index 7888d146357d..16e821c3d192 100644 Binary files a/icons/obj/structures/mortar.dmi and b/icons/obj/structures/mortar.dmi differ diff --git a/icons/obj/structures/tables.dmi b/icons/obj/structures/tables.dmi index bee6f34772be..39783bfd8b4d 100644 Binary files a/icons/obj/structures/tables.dmi and b/icons/obj/structures/tables.dmi differ diff --git a/sound/machines/pda_ping.ogg b/sound/machines/pda_ping.ogg new file mode 100644 index 000000000000..2f3135bc3c22 Binary files /dev/null and b/sound/machines/pda_ping.ogg differ diff --git a/tgui/packages/tgui/interfaces/WorkingJoe.jsx b/tgui/packages/tgui/interfaces/WorkingJoe.jsx index fed64c923116..4864631aa152 100644 --- a/tgui/packages/tgui/interfaces/WorkingJoe.jsx +++ b/tgui/packages/tgui/interfaces/WorkingJoe.jsx @@ -63,12 +63,22 @@ const Login = (props) => { const MainMenu = (props) => { const { data, act } = useBackend(); - const { logged_in, access_text, last_page, current_menu, access_level } = - data; + const { + logged_in, + access_text, + last_page, + current_menu, + access_level, + notify_sounds, + } = data; let can_request_access = 'Yes'; if (access_level > 2) { can_request_access = 'No'; } + let soundicon = 'volume-high'; + if (!notify_sounds) { + soundicon = 'volume-xmark'; + } return ( <> @@ -86,11 +96,17 @@ const MainMenu = (props) => {