From f2471a869df29217d88a8106850ba107ff0020c8 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Tue, 20 Jun 2023 13:37:00 -0400 Subject: [PATCH 01/54] The nuclear option (#3470) # About the pull request This PR adds a nuke as something buyable at the tier 4 level of intel. It takes 35 points in total to reach it (costing 20 points by itself). You cannot buy it before 120 minutes. To use the nuke you must first decrypt the authorization codes on the surface. This requires holding both comms towers on the surface for 10 minutes. After it's decrypted you are free to arm the nuke, without requiring the comm towers, and it will detonate in 60 seconds. # Explain why it's good for the game Coming soonTM # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow add: Re-added the nuke that you can buy via intel at tier 4. Only purchasable past 120 minutes. Requires holding both groundside comms towers for authorization decryption before being able to be armed. /:cl: --- code/__DEFINES/dcs/signals/signals_global.dm | 3 + code/__DEFINES/objects.dm | 11 +- code/datums/supply_packs/operations.dm | 8 + code/game/machinery/nuclearbomb.dm | 388 +++++++++++++----- .../machinery/telecomms/telecomunications.dm | 3 + code/modules/cm_tech/tech.dm | 7 + .../cm_tech/techs/abstract/repeatable.dm | 5 - .../cm_tech/techs/abstract/transitory.dm | 19 + .../cm_tech/techs/marine/tier4/nuke.dm | 43 ++ colonialmarines.dme | 1 + icons/effects/techtree/tech.dmi | Bin 4136 -> 4324 bytes tgui/packages/tgui/interfaces/NuclearBomb.js | 32 +- 12 files changed, 407 insertions(+), 113 deletions(-) create mode 100644 code/modules/cm_tech/techs/marine/tier4/nuke.dm diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm index c3d51b2d65cd..90a50fad138c 100644 --- a/code/__DEFINES/dcs/signals/signals_global.dm +++ b/code/__DEFINES/dcs/signals/signals_global.dm @@ -48,5 +48,8 @@ // Used for smothering fires upon weather event start/stop #define COMSIG_GLOB_WEATHER_CHANGE "!weather_event_changed" +/// From /obj/structure/machinery/telecomms/proc/tcomms_shutdown(), called when the relay turns off +#define COMSIG_GLOB_GROUNDSIDE_TELECOMM_TURNED_OFF "!groundside_telecomm_turned_off" + /// From /datum/admins/proc/force_predator_round() #define COMSIG_GLOB_PREDATOR_ROUND_TOGGLED "!predator_round_toglged" diff --git a/code/__DEFINES/objects.dm b/code/__DEFINES/objects.dm index 5617a2b47ec6..0a34ac9d6fe9 100644 --- a/code/__DEFINES/objects.dm +++ b/code/__DEFINES/objects.dm @@ -136,11 +136,16 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse #define CLEANABLE_MISC "misc" //Anything else //For nuke announcements -#define NUKE_SHOW_TIMER_TEN_SEC 1 -#define NUKE_SHOW_TIMER_MINUTE 2 -#define NUKE_SHOW_TIMER_HALF 4 +#define NUKE_SHOW_TIMER_TEN_SEC (1<<0) +#define NUKE_SHOW_TIMER_MINUTE (1<<1) +#define NUKE_SHOW_TIMER_HALF (1<<2) #define NUKE_SHOW_TIMER_ALL (NUKE_SHOW_TIMER_TEN_SEC|NUKE_SHOW_TIMER_MINUTE|NUKE_SHOW_TIMER_HALF) +#define NUKE_DECRYPT_SHOW_TIMER_COMPLETE (1<<3) +#define NUKE_DECRYPT_SHOW_TIMER_MINUTE (1<<4) +#define NUKE_DECRYPT_SHOW_TIMER_HALF (1<<5) +#define NUKE_DECRYPT_SHOW_TIMER_ALL (NUKE_SHOW_TIMER_TEN_SEC|NUKE_SHOW_TIMER_HALF|NUKE_DECRYPT_SHOW_TIMER_COMPLETE|NUKE_DECRYPT_SHOW_TIMER_MINUTE|NUKE_DECRYPT_SHOW_TIMER_HALF) + //For recipes #define ONE_TYPE_PER_TURF 1 #define ONE_TYPE_PER_BORDER 2 diff --git a/code/datums/supply_packs/operations.dm b/code/datums/supply_packs/operations.dm index cc4408659d09..610503d6c25d 100644 --- a/code/datums/supply_packs/operations.dm +++ b/code/datums/supply_packs/operations.dm @@ -101,6 +101,14 @@ group = "Operations" iteration_needed = null +/datum/supply_packs/technuclearbomb + name = "Intel Operational Nuke" + cost = 0 + containertype = /obj/structure/machinery/nuclearbomb/tech + buyable = 0 + group = "Operations" + iteration_needed = null + /datum/supply_packs/spec_kits name = "Weapons Specialist Kits" contains = list( diff --git a/code/game/machinery/nuclearbomb.dm b/code/game/machinery/nuclearbomb.dm index 7dcdb9e39914..6c0ec4cc0389 100644 --- a/code/game/machinery/nuclearbomb.dm +++ b/code/game/machinery/nuclearbomb.dm @@ -55,31 +55,35 @@ var/bomb_set = FALSE /obj/structure/machinery/nuclearbomb/process() . = ..() - if(timing) - bomb_set = TRUE //So long as there is one nuke timing, it means one nuke is armed. - timeleft = explosion_time - world.time - if(world.time >= explosion_time) - explode() - //3 warnings: 1. Halfway through, 2. 1 minute left, 3. 10 seconds left. - //this structure allows varedits to var/timeleft without losing or spamming warnings. - else if(timer_announcements_flags) - if(timer_announcements_flags & NUKE_SHOW_TIMER_HALF) - if(timeleft <= initial(timeleft) / 2 && timeleft >= initial(timeleft) / 2 - 30) - announce_to_players(NUKE_SHOW_TIMER_HALF) - timer_announcements_flags &= ~NUKE_SHOW_TIMER_HALF - return - if(timer_announcements_flags & NUKE_SHOW_TIMER_MINUTE) - if(timeleft <= 600 && timeleft >= 570) - announce_to_players(NUKE_SHOW_TIMER_MINUTE) - timer_announcements_flags = NUKE_SHOW_TIMER_TEN_SEC - return - if(timer_announcements_flags & NUKE_SHOW_TIMER_TEN_SEC) - if(timeleft <= 100 && timeleft >= 70) - announce_to_players(NUKE_SHOW_TIMER_TEN_SEC) - timer_announcements_flags = 0 - return - else - stop_processing() + if(!timing) + update_minimap_icon() + return PROCESS_KILL + + bomb_set = TRUE //So long as there is one nuke timing, it means one nuke is armed. + timeleft = explosion_time - world.time + if(world.time >= explosion_time) + explode() + return + //3 warnings: 1. Halfway through, 2. 1 minute left, 3. 10 seconds left. + //this structure allows varedits to var/timeleft without losing or spamming warnings. + if(!timer_announcements_flags) + return + + if(timer_announcements_flags & NUKE_SHOW_TIMER_HALF) + if(timeleft <= initial(timeleft) / 2 && timeleft >= initial(timeleft) / 2 - 30) + announce_to_players(NUKE_SHOW_TIMER_HALF) + timer_announcements_flags &= ~NUKE_SHOW_TIMER_HALF + return + if(timer_announcements_flags & NUKE_SHOW_TIMER_MINUTE) + if(timeleft <= 600 && timeleft >= 570) + announce_to_players(NUKE_SHOW_TIMER_MINUTE) + timer_announcements_flags = NUKE_SHOW_TIMER_TEN_SEC + return + if(timer_announcements_flags & NUKE_SHOW_TIMER_TEN_SEC) + if(timeleft <= 100 && timeleft >= 70) + announce_to_players(NUKE_SHOW_TIMER_TEN_SEC) + timer_announcements_flags = 0 + return /obj/structure/machinery/nuclearbomb/attack_alien(mob/living/carbon/xenomorph/M) INVOKE_ASYNC(src, TYPE_PROC_REF(/atom, attack_hand), M) @@ -87,10 +91,10 @@ var/bomb_set = FALSE /obj/structure/machinery/nuclearbomb/attackby(obj/item/O as obj, mob/user as mob) if(anchored && timing && bomb_set && HAS_TRAIT(O, TRAIT_TOOL_WIRECUTTERS)) - user.visible_message(SPAN_DANGER("[user] begins to defuse \the [src]."), SPAN_DANGER("You begin to defuse \the [src]. This will take some time...")) + user.visible_message(SPAN_INFO("[user] begins to defuse \the [src]."), SPAN_INFO("You begin to defuse \the [src]. This will take some time...")) if(do_after(user, 150 * user.get_skill_duration_multiplier(SKILL_ENGINEER), INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) disable() - playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) + playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1) return ..() @@ -103,12 +107,12 @@ var/bomb_set = FALSE if(deployable) if(!ishuman(user) && !isqueen(user)) - to_chat(usr, SPAN_DANGER("You don't have the dexterity to do this!")) + to_chat(usr, SPAN_INFO("You don't have the dexterity to do this!")) return if(isqueen(user)) if(timing && bomb_set) - user.visible_message(SPAN_DANGER("[user] begins to defuse \the [src]."), SPAN_DANGER("You begin to defuse \the [src]. This will take some time...")) + user.visible_message(SPAN_INFO("[user] begins to defuse \the [src]."), SPAN_INFO("You begin to defuse \the [src]. This will take some time...")) if(do_after(user, 5 SECONDS, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) disable() return @@ -162,37 +166,38 @@ var/bomb_set = FALSE if(timing == -1) return - if(!ishuman(usr)) + if(!ishuman(ui.user)) return - if(!allowed(usr)) - to_chat(usr, SPAN_DANGER("Access denied!")) + if(!allowed(ui.user)) + to_chat(ui.user, SPAN_INFO("Access denied!")) return if(!anchored) - to_chat(usr, SPAN_DANGER("Engage anchors first!")) + to_chat(ui.user, SPAN_INFO("Engage anchors first!")) return if(safety) - to_chat(usr, SPAN_DANGER("The safety is still on.")) + to_chat(ui.user, SPAN_INFO("The safety is still on.")) return if(!A.can_build_special) - to_chat(usr, SPAN_DANGER("You cannot deploy [src] here!")) + to_chat(ui.user, SPAN_INFO("You cannot deploy [src] here!")) return - if(usr.action_busy) + if(ui.user.action_busy) return - usr.visible_message(SPAN_WARNING("[usr] begins to [timing ? "disengage" : "engage"] [src]!"), SPAN_WARNING("You begin to [timing ? "disengage" : "engage"] [src].")) + ui.user.visible_message(SPAN_WARNING("[ui.user] begins to [timing ? "disengage" : "engage"] [src]!"), SPAN_WARNING("You begin to [timing ? "disengage" : "engage"] [src].")) being_used = TRUE - ui = SStgui.try_update_ui(usr, src, ui) - if(do_after(usr, 50, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) + ui = SStgui.try_update_ui(ui.user, src, ui) + if(do_after(ui.user, 50, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) timing = !timing if(timing) if(!safety) bomb_set = TRUE explosion_time = world.time + timeleft + update_minimap_icon() start_processing() announce_to_players() message_admins("\The [src] has been activated by [key_name(ui.user, 1)] [ADMIN_JMP_USER(ui.user)]") @@ -201,28 +206,28 @@ var/bomb_set = FALSE else disable() message_admins("\The [src] has been deactivated by [key_name(ui.user, 1)] [ADMIN_JMP_USER(ui.user)]") - playsound(src.loc, 'sound/effects/thud.ogg', 100, 1) + playsound(loc, 'sound/effects/thud.ogg', 100, 1) being_used = FALSE . = TRUE if("toggleSafety") - if(!allowed(usr)) - to_chat(usr, SPAN_DANGER("Access denied!")) + if(!allowed(ui.user)) + to_chat(ui.user, SPAN_INFO("Access denied!")) return if(timing) - to_chat(usr, SPAN_DANGER("Disengage first!")) + to_chat(ui.user, SPAN_INFO("Disengage first!")) return if(!A.can_build_special) - to_chat(usr, SPAN_DANGER("You cannot deploy [src] here!")) + to_chat(ui.user, SPAN_INFO("You cannot deploy [src] here!")) return - if(usr.action_busy) + if(ui.user.action_busy) return - usr.visible_message(SPAN_WARNING("[usr] begins to [safety ? "disable" : "enable"] the safety on [src]!"), SPAN_WARNING("You begin to [safety ? "disable" : "enable"] the safety on [src].")) + ui.user.visible_message(SPAN_WARNING("[ui.user] begins to [safety ? "disable" : "enable"] the safety on [src]!"), SPAN_WARNING("You begin to [safety ? "disable" : "enable"] the safety on [src].")) being_used = TRUE - ui = SStgui.try_update_ui(usr, src, ui) - if(do_after(usr, 50, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) + ui = SStgui.try_update_ui(ui.user, src, ui) + if(do_after(ui.user, 50, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) safety = !safety - playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1) + playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1) being_used = FALSE if(safety) timing = FALSE @@ -230,63 +235,55 @@ var/bomb_set = FALSE . = TRUE if("toggleCommandLockout") - if(!ishuman(usr)) + if(!ishuman(ui.user)) return - if(!allowed(usr)) - to_chat(usr, SPAN_DANGER("Access denied!")) + if(!allowed(ui.user)) + to_chat(ui.user, SPAN_INFO("Access denied!")) return if(command_lockout) command_lockout = FALSE req_one_access = list() - to_chat(usr, SPAN_DANGER("Command lockout disengaged.")) + to_chat(ui.user, SPAN_INFO("Command lockout disengaged.")) else //Check if they have command access var/list/acc = list() - var/mob/living/carbon/human/H = usr + var/mob/living/carbon/human/H = ui.user if(H.wear_id) acc += H.wear_id.GetAccess() if(H.get_active_hand()) acc += H.get_active_hand().GetAccess() if(!(ACCESS_MARINE_COMMAND in acc)) - to_chat(usr, SPAN_DANGER("Access denied!")) + to_chat(ui.user, SPAN_INFO("Access denied!")) return command_lockout = TRUE req_one_access = list(ACCESS_MARINE_COMMAND) - to_chat(usr, SPAN_DANGER("Command lockout engaged.")) + to_chat(ui.user, SPAN_INFO("Command lockout engaged.")) . = TRUE if("toggleAnchor") if(timing) - to_chat(usr, SPAN_DANGER("Disengage first!")) + to_chat(ui.user, SPAN_INFO("Disengage first!")) return if(!A.can_build_special) - to_chat(usr, SPAN_DANGER("You cannot deploy [src] here!")) + to_chat(ui.user, SPAN_INFO("You cannot deploy [src] here!")) return - if(usr.action_busy) + if(ui.user.action_busy) return being_used = TRUE - ui = SStgui.try_update_ui(usr, src, ui) - if(do_after(usr, 50, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) + ui = SStgui.try_update_ui(ui.user, src, ui) + if(do_after(ui.user, 50, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) if(!anchored) - visible_message(SPAN_DANGER("With a steely snap, bolts slide out of [src] and anchor it to the flooring.")) + visible_message(SPAN_INFO("With a steely snap, bolts slide out of [src] and anchor it to the flooring.")) else - visible_message(SPAN_DANGER("The anchoring bolts slide back into the depths of [src].")) - playsound(src.loc, 'sound/items/Deconstruct.ogg', 100, 1) + visible_message(SPAN_INFO("The anchoring bolts slide back into the depths of [src].")) + playsound(loc, 'sound/items/Deconstruct.ogg', 100, 1) anchored = !anchored being_used = FALSE . = TRUE update_icon() - add_fingerprint(usr) - -/obj/structure/machinery/nuclearbomb/start_processing() - . = ..() - update_minimap_icon() - -/obj/structure/machinery/nuclearbomb/stop_processing() - . = ..() - update_minimap_icon() + add_fingerprint(ui.user) /obj/structure/machinery/nuclearbomb/verb/make_deployable() set category = "Object" @@ -297,12 +294,12 @@ var/bomb_set = FALSE return if(!ishuman(usr)) - to_chat(usr, SPAN_DANGER("You don't have the dexterity to do this!")) + to_chat(usr, SPAN_INFO("You don't have the dexterity to do this!")) return var/area/A = get_area(src) if(!A.can_build_special) - to_chat(usr, SPAN_DANGER("You don't want to deploy this here!")) + to_chat(usr, SPAN_INFO("You don't want to deploy this here!")) return usr.visible_message(SPAN_WARNING("[usr] begins to [deployable ? "close" : "adjust"] several panels to make [src] [deployable ? "undeployable" : "deployable"]."), SPAN_WARNING("You begin to [deployable ? "close" : "adjust"] several panels to make [src] [deployable ? "undeployable" : "deployable"].")) @@ -314,26 +311,25 @@ var/bomb_set = FALSE else deployable = TRUE anchored = TRUE - playsound(src.loc, 'sound/items/Deconstruct.ogg', 100, 1) + playsound(loc, 'sound/items/Deconstruct.ogg', 100, 1) being_used = FALSE update_icon() //unified all announcements to one proc /obj/structure/machinery/nuclearbomb/proc/announce_to_players(timer_warning) + + var/list/humans_other = GLOB.human_mob_list + GLOB.dead_mob_list + var/list/humans_uscm = list() + for(var/mob/current_mob as anything in humans_other) + if(current_mob.stat != CONSCIOUS || isyautja(current_mob)) + humans_other -= current_mob + continue + if(current_mob.faction == FACTION_MARINE || current_mob.faction == FACTION_SURVIVOR) //separating marines from other factions. Survs go here too + humans_uscm += current_mob + humans_other -= current_mob + if(timer_warning) //we check for timer warnings first - //humans part - var/list/humans_other = GLOB.human_mob_list + GLOB.dead_mob_list - var/list/humans_USCM = list() - for(var/mob/M in humans_other) - var/mob/living/carbon/human/H = M - if(istype(H)) //if it's unconsious human or yautja, we remove them - if(H.stat != CONSCIOUS || isyautja(H)) - humans_other.Remove(M) - continue - if(M.faction == FACTION_MARINE || M.faction == FACTION_SURVIVOR) //separating marines from other factions. Survs go here too - humans_USCM += M - humans_other -= M - announcement_helper("WARNING.\n\nDETONATION IN [round(timeleft/10)] SECONDS.", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_USCM, 'sound/misc/notice1.ogg') + announcement_helper("WARNING.\n\nDETONATION IN [round(timeleft/10)] SECONDS.", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_uscm, 'sound/misc/notice1.ogg') announcement_helper("WARNING.\n\nDETONATION IN [round(timeleft/10)] SECONDS.", "HQ Intel Division", humans_other, 'sound/misc/notice1.ogg') //preds part var/t_left = duration2text_sec(round(rand(timeleft - timeleft / 10, timeleft + timeleft / 10))) @@ -354,21 +350,9 @@ var/bomb_set = FALSE xeno_announcement(SPAN_XENOANNOUNCE(warning), hive.hivenumber, XENO_GENERAL_ANNOUNCE) return - //deal with start/stop announcements for players - var/list/humans_other = GLOB.human_mob_list + GLOB.dead_mob_list - var/list/humans_USCM = list() - for(var/mob/M in humans_other) - var/mob/living/carbon/human/H = M - if(istype(H)) //if it's unconsious human or yautja, we remove them - if(H.stat != CONSCIOUS || isyautja(H)) - humans_other.Remove(M) - continue - if(M.faction == FACTION_MARINE || M.faction == FACTION_SURVIVOR) //separating marines from other factions. Survs go here too - humans_USCM += M - humans_other -= M var/datum/hive_status/hive if(timing) - announcement_helper("ALERT.\n\nNUCLEAR EXPLOSIVE ORDNANCE ACTIVATED.\n\nDETONATION IN [round(timeleft/10)] SECONDS.", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_USCM, 'sound/misc/notice1.ogg') + announcement_helper("ALERT.\n\nNUCLEAR EXPLOSIVE ORDNANCE ACTIVATED.\n\nDETONATION IN [round(timeleft/10)] SECONDS.", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_uscm, 'sound/misc/notice1.ogg') announcement_helper("ALERT.\n\nNUCLEAR EXPLOSIVE ORDNANCE ACTIVATED.\n\nDETONATION IN [round(timeleft/10)] SECONDS.", "HQ Nuclear Tracker", humans_other, 'sound/misc/notice1.ogg') var/t_left = duration2text_sec(round(rand(timeleft - timeleft / 10, timeleft + timeleft / 10))) yautja_announcement(SPAN_YAUTJABOLDBIG("WARNING!
A human Purification Device has been detected. You have approximately [t_left] to abandon the hunting grounds before it activates.")) @@ -378,7 +362,7 @@ var/bomb_set = FALSE continue xeno_announcement(SPAN_XENOANNOUNCE("The tallhosts have deployed a hive killer at [get_area_name(loc)]! Stop it at all costs!"), hive.hivenumber, XENO_GENERAL_ANNOUNCE) else - announcement_helper("ALERT.\n\nNUCLEAR EXPLOSIVE ORDNANCE DEACTIVATED.", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_USCM, 'sound/misc/notice1.ogg') + announcement_helper("ALERT.\n\nNUCLEAR EXPLOSIVE ORDNANCE DEACTIVATED.", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_uscm, 'sound/misc/notice1.ogg') announcement_helper("ALERT.\n\nNUCLEAR EXPLOSIVE ORDNANCE DEACTIVATED.", "HQ Intel Division", humans_other, 'sound/misc/notice1.ogg') yautja_announcement(SPAN_YAUTJABOLDBIG("WARNING!
The human Purification Device's signature has disappeared.")) for(var/hivenumber in GLOB.hive_datum) @@ -401,6 +385,7 @@ var/bomb_set = FALSE /obj/structure/machinery/nuclearbomb/proc/explode() if(safety) timing = FALSE + update_minimap_icon() stop_processing() update_icon() return FALSE @@ -422,3 +407,200 @@ var/bomb_set = FALSE bomb_set = FALSE SSminimaps.remove_marker(src) return ..() + +/obj/structure/machinery/nuclearbomb/tech + var/decryption_time = 10 MINUTES + var/decryption_end_time = null + var/decrypting = FALSE + + timeleft = 1 MINUTES + timer_announcements_flags = NUKE_DECRYPT_SHOW_TIMER_ALL + + var/list/linked_decryption_towers + +/obj/structure/machinery/nuclearbomb/tech/Initialize(mapload) + . = ..() + + linked_decryption_towers = list() + + return INITIALIZE_HINT_LATELOAD + +/obj/structure/machinery/nuclearbomb/tech/LateInitialize() + . = ..() + + for(var/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/possible_telecomm in GLOB.all_static_telecomms_towers) + if(is_ground_level(possible_telecomm.z)) + linked_decryption_towers += possible_telecomm + + RegisterSignal(SSdcs, COMSIG_GLOB_GROUNDSIDE_TELECOMM_TURNED_OFF, PROC_REF(connected_comm_shutdown)) + +/obj/structure/machinery/nuclearbomb/tech/ui_data(mob/user) + . = ..() + + .["decrypting"] = decrypting + .["decryption_time"] = duration2text_sec(decryption_time) + + .["decryption_complete"] = decryption_time ? FALSE : TRUE + +/obj/structure/machinery/nuclearbomb/tech/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + if(..()) + return + + switch(action) + if("toggleEncryption") + if(!ishuman(ui.user)) + return + + if(!allowed(ui.user)) + to_chat(ui.user, SPAN_INFO("Access denied!")) + return + + if(!anchored) + to_chat(ui.user, SPAN_INFO("Engage anchors first!")) + return + + var/area/current_area = get_area(src) + if(!current_area.can_build_special) + to_chat(ui.user, SPAN_INFO("You cannot deploy [src] here!")) + return + + if(is_ground_level(z)) + for(var/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/telecomm_unit in linked_decryption_towers) + if(!telecomm_unit.on) + to_chat(ui.user, SPAN_INFO("The groundside telecommunication relays must be activated!")) + return + + if(ui.user.action_busy) + return + + if(being_used) + return + + ui.user.visible_message(SPAN_WARNING("[ui.user] begins to [decrypting ? "stop the decryption process." : "start decrypting."]!"), SPAN_WARNING("You begin to [decrypting ? "stop the decryption process." : "start decrypting."].")) + being_used = TRUE + ui = SStgui.try_update_ui(ui.user, src, ui) + if(do_after(ui.user, 50, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) + decrypting = !decrypting + if(decrypting) + //add signal handlers + decryption_end_time = world.time + decryption_time + start_processing() + announce_to_players() + message_admins("[src]'s encryption process has been started by [key_name(ui.user, 1)] [ADMIN_JMP_USER(ui.user)]") + else + //remove signal handlers + decryption_end_time = null + announce_to_players() + message_admins("[src]'s encryption process has been deactivated by [key_name(ui.user, 1)] [ADMIN_JMP_USER(ui.user)]") + playsound(loc, 'sound/effects/thud.ogg', 100, 1) + being_used = FALSE + return TRUE + +/obj/structure/machinery/nuclearbomb/tech/process() + if(!decrypting) + return ..() + + decryption_time = decryption_end_time - world.time + + if(world.time > decryption_end_time) + decrypting = FALSE + decryption_time = 0 + announce_to_players(NUKE_DECRYPT_SHOW_TIMER_COMPLETE) + timer_announcements_flags &= ~NUKE_DECRYPT_SHOW_TIMER_COMPLETE + return PROCESS_KILL + + if(!timer_announcements_flags) + return + + if(timer_announcements_flags & NUKE_DECRYPT_SHOW_TIMER_HALF) + if(decryption_time <= initial(decryption_time) / 2 && decryption_time >= initial(decryption_time) / 2 - 30) + announce_to_players(NUKE_DECRYPT_SHOW_TIMER_HALF) + timer_announcements_flags &= ~NUKE_DECRYPT_SHOW_TIMER_HALF + return + if(timer_announcements_flags & NUKE_DECRYPT_SHOW_TIMER_MINUTE) + if(decryption_time <= 600 && decryption_time >= 570) + announce_to_players(NUKE_DECRYPT_SHOW_TIMER_MINUTE) + timer_announcements_flags &= ~NUKE_DECRYPT_SHOW_TIMER_MINUTE + return + +/obj/structure/machinery/nuclearbomb/tech/announce_to_players(timer_warning) + if(!decryption_time && (timer_warning != NUKE_DECRYPT_SHOW_TIMER_COMPLETE)) + return ..() + + var/list/humans_other = GLOB.human_mob_list + GLOB.dead_mob_list + var/list/humans_uscm = list() + for(var/mob/current_mob as anything in humans_other) + var/mob/living/carbon/human/current_human = current_mob + if(istype(current_human)) //if it's unconsious human or yautja, we remove them + if(current_human.stat != CONSCIOUS || isyautja(current_human)) + humans_other -= current_mob + continue + if(current_mob.faction == FACTION_MARINE || current_mob.faction == FACTION_SURVIVOR) + humans_uscm += current_mob + humans_other -= current_mob + + if(timer_warning) + if(timer_warning == NUKE_DECRYPT_SHOW_TIMER_COMPLETE) + announcement_helper("DECRYPTION COMPLETE", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_uscm, 'sound/misc/notice1.ogg') + announcement_helper("DECRYPTION COMPLETE", "HQ Intel Division", humans_other, 'sound/misc/notice1.ogg') + + yautja_announcement(SPAN_YAUTJABOLDBIG("WARNING!\n\nThe human Purification Device is able to be activated.")) + + var/datum/hive_status/hive + for(var/hivenumber in GLOB.hive_datum) + hive = GLOB.hive_datum[hivenumber] + if(!length(hive.totalXenos)) + return + xeno_announcement(SPAN_XENOANNOUNCE("The hive killer is ready to be activated! Assault at once!"), hive.hivenumber, XENO_GENERAL_ANNOUNCE) + return + + announcement_helper("DECRYPTION IN [round(decryption_time/10)] SECONDS.", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_uscm, 'sound/misc/notice1.ogg') + announcement_helper("DECRYPTION IN [round(decryption_time/10)] SECONDS.", "HQ Intel Division", humans_other, 'sound/misc/notice1.ogg') + + //preds part + var/time_left = duration2text_sec(round(rand(decryption_time - decryption_time / 10, decryption_time + decryption_time / 10))) + yautja_announcement(SPAN_YAUTJABOLDBIG("WARNING!\n\nYou have approximately [time_left] seconds to abandon the hunting grounds before human Purification Device is able to be activated.")) + + //xenos part + var/warning = "Hive killer is almost prepared to be activated!" + if(timer_warning & NUKE_DECRYPT_SHOW_TIMER_HALF) + warning = "Hive killer is halfway through its initial phase!" + + var/datum/hive_status/hive + for(var/hivenumber in GLOB.hive_datum) + hive = GLOB.hive_datum[hivenumber] + if(!hive.totalXenos.len) + return + xeno_announcement(SPAN_XENOANNOUNCE(warning), hive.hivenumber, XENO_GENERAL_ANNOUNCE) + return + + var/datum/hive_status/hive + if(decrypting) + announcement_helper("ALERT.\n\nNUCLEAR EXPLOSIVE ORDNANCE DECRYPTION STARTED.\n\nDECRYPTION IN [round(decryption_time/10)] SECONDS.", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_uscm, 'sound/misc/notice1.ogg') + announcement_helper("ALERT.\n\nNUCLEAR EXPLOSIVE ORDNANCE DECRYPTION STARTED.\n\nDECRYPTION IN [round(decryption_time/10)] SECONDS.", "HQ Nuclear Tracker", humans_other, 'sound/misc/notice1.ogg') + var/time_left = duration2text_sec(round(rand(decryption_time - decryption_time / 10, decryption_time + decryption_time / 10))) + yautja_announcement(SPAN_YAUTJABOLDBIG("WARNING!
A human Purification Device has been detected. You have approximately [time_left] before it finishes its initial phase.")) + for(var/hivenumber in GLOB.hive_datum) + hive = GLOB.hive_datum[hivenumber] + if(!length(hive.totalXenos)) + continue + xeno_announcement(SPAN_XENOANNOUNCE("The tallhosts have started the initial phase of a hive killer at [get_area_name(loc)]! Destroy their communications relays!"), hive.hivenumber, XENO_GENERAL_ANNOUNCE) + return + + announcement_helper("ALERT.\n\nNUCLEAR EXPLOSIVE DECRYPTION HALTED.", "[MAIN_AI_SYSTEM] Nuclear Tracker", humans_uscm, 'sound/misc/notice1.ogg') + announcement_helper("ALERT.\n\nNUCLEAR EXPLOSIVE DECRYPTION HALTED.", "HQ Intel Division", humans_other, 'sound/misc/notice1.ogg') + yautja_announcement(SPAN_YAUTJABOLDBIG("WARNING!
The human Purification Device's signature has disappeared.")) + for(var/hivenumber in GLOB.hive_datum) + hive = GLOB.hive_datum[hivenumber] + if(!length(hive.totalXenos)) + continue + xeno_announcement(SPAN_XENOANNOUNCE("The hive killer's initial phase has been halted! Rejoice!"), hive.hivenumber, XENO_GENERAL_ANNOUNCE) + +/obj/structure/machinery/nuclearbomb/tech/proc/connected_comm_shutdown(obj/structure/machinery/telecomms/relay/preset/tower/telecomm_unit) + SIGNAL_HANDLER + + if(!decrypting) + return + + decrypting = FALSE + announce_to_players() diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 324a358d041f..255d70f45870 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -71,6 +71,9 @@ GLOBAL_LIST_EMPTY_TYPED(telecomms_list, /obj/structure/machinery/telecomms) // When effectively shut down /obj/structure/machinery/telecomms/proc/tcomms_shutdown() on = FALSE + + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_GROUNDSIDE_TELECOMM_TURNED_OFF) + if(tcomms_machine) SSradio.remove_tcomm_machine(src) diff --git a/code/modules/cm_tech/tech.dm b/code/modules/cm_tech/tech.dm index 5c37dafef3f3..dea505f3237a 100644 --- a/code/modules/cm_tech/tech.dm +++ b/code/modules/cm_tech/tech.dm @@ -21,6 +21,9 @@ var/background_icon = "background" var/background_icon_locked = "marine" + var/announce_name + var/announce_message + /datum/tech/proc/can_unlock(mob/M) SHOULD_CALL_PARENT(TRUE) @@ -68,6 +71,10 @@ log_admin("[key_name_admin(user)] has bought '[name]' via tech points.") holder.spend_points(required_points) update_icon(node) + + if(!(tech_flags & TECH_FLAG_NO_ANNOUNCE) && announce_message && announce_name) + marine_announcement(announce_message, announce_name, 'sound/misc/notice2.ogg') + return TRUE /datum/tech/ui_status(mob/user, datum/ui_state/state) diff --git a/code/modules/cm_tech/techs/abstract/repeatable.dm b/code/modules/cm_tech/techs/abstract/repeatable.dm index e9706538071c..4b240814e0c6 100644 --- a/code/modules/cm_tech/techs/abstract/repeatable.dm +++ b/code/modules/cm_tech/techs/abstract/repeatable.dm @@ -4,9 +4,6 @@ /datum/tech/repeatable name = "Repeatable Tech" - var/announce_name - var/announce_message - tech_flags = TECH_FLAG_MULTIUSE var/purchase_cooldown = 10 SECONDS var/next_purchase = 0 @@ -35,8 +32,6 @@ /datum/tech/repeatable/on_unlock() ..() - if(!(tech_flags & TECH_FLAG_NO_ANNOUNCE) && announce_message && announce_name) - marine_announcement(announce_message, announce_name, 'sound/misc/notice2.ogg') next_purchase = world.time + purchase_cooldown required_points += increase_per_purchase diff --git a/code/modules/cm_tech/techs/abstract/transitory.dm b/code/modules/cm_tech/techs/abstract/transitory.dm index 09301b6ba205..7798b6053d0e 100644 --- a/code/modules/cm_tech/techs/abstract/transitory.dm +++ b/code/modules/cm_tech/techs/abstract/transitory.dm @@ -87,3 +87,22 @@ required_points = 5 flags = TREE_FLAG_MARINE + +/datum/tech/transitory/tier4 + name = "Unlock Tier 4" + tier = /datum/tier/three_transition_four + + before = /datum/tier/three + next = /datum/tier/four + +/datum/tech/transitory/tier4/xeno + techs_to_unlock = 0 + required_points = 5 + + flags = TREE_FLAG_XENO + +/datum/tech/transitory/tier4/marine + techs_to_unlock = 0 + required_points = 5 + + flags = TREE_FLAG_MARINE diff --git a/code/modules/cm_tech/techs/marine/tier4/nuke.dm b/code/modules/cm_tech/techs/marine/tier4/nuke.dm new file mode 100644 index 000000000000..eb4e64b59951 --- /dev/null +++ b/code/modules/cm_tech/techs/marine/tier4/nuke.dm @@ -0,0 +1,43 @@ +#define NUKE_UNLOCK_TIME (120 MINUTES) + +/datum/tech/nuke + name = "Nuclear Device" + //desc = "Purchase a nuclear device. Only able to purchase after X minutes into the operation. It's the only way to be sure." //See New() + icon_state = "nuke" + + required_points = 20 + + tier = /datum/tier/four + + announce_name = "NUCLEAR ARSENAL ACQUIRED" + announce_message = "A nuclear device has been purchased and will be delivered to requisitions via ASRS." + + flags = TREE_FLAG_MARINE + +/datum/tech/nuke/New() + desc = "Purchase a nuclear device. Only able to purchase [NUKE_UNLOCK_TIME / (1 MINUTES)] minutes into the operation. It's the only way to be sure." + +/datum/tech/nuke/on_unlock() + . = ..() + + var/datum/supply_order/new_order = new /datum/supply_order() + new_order.ordernum = supply_controller.ordernum + supply_controller.ordernum++ + new_order.object = supply_controller.supply_packs["Intel Operational Nuke"] + new_order.orderedby = MAIN_AI_SYSTEM + + supply_controller.shoppinglist += new_order + +/datum/tech/nuke/can_unlock(mob/unlocking_mob) + . = ..() + + if(!.) + return + + if(ROUND_TIME < NUKE_UNLOCK_TIME) + to_chat(unlocking_mob, SPAN_WARNING("You cannot purchase this node before [NUKE_UNLOCK_TIME / (1 MINUTES)] minutes into the operation.")) + return FALSE + + return TRUE + +#undef NUKE_UNLOCK_TIME diff --git a/colonialmarines.dme b/colonialmarines.dme index 9feb76faf408..6e5bda16e73d 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -1555,6 +1555,7 @@ #include "code\modules\cm_tech\techs\marine\tier1\points.dm" #include "code\modules\cm_tech\techs\marine\tier2\orbital_ammo.dm" #include "code\modules\cm_tech\techs\marine\tier3\cryorine.dm" +#include "code\modules\cm_tech\techs\marine\tier4\nuke.dm" #include "code\modules\cm_tech\trees\marine.dm" #include "code\modules\customitems\item_spawning.dm" #include "code\modules\decorators\admin_runtime_decorator.dm" diff --git a/icons/effects/techtree/tech.dmi b/icons/effects/techtree/tech.dmi index a255a0d0e544e9280e09d64d18811a942bcd3c04..d88106f82d1153996f435386371644091f98ea64 100644 GIT binary patch delta 4109 zcmV+o5c2P+AmkyCBLV>tktK5s0RaK=%|ikL0`AK~k(fdc9UUDYARuN~)E*ulA|fJ@ z-57rb1OWpB0|W#F1qB5M2L~}SHUa?wz`(#+9=kYi%=z>;rffb+O|oe-!20$h6lU-1lKXCP61P z(beSDsSR%dp#d)%LwusDh(-&IeKLQ7g+IX<{)vNJ`Tb^u2=KDd^pTO4r}Gih$o|_0GHRvDyaUEk-qf zKVW14f5>PIKtBKG0Oq?s;QLkyVBUV)0W2lmY8+~qsCRmR?|a%cKra7yK=zwHphp@3 z{wN~{_~VS01r#7jWiy-qT0nmvDgoS*1vQ(Nk`ZAAU{*T?sQJKxF=0g=To-UVMbz*C zXS;R45iJ;(KOYeI^md;Cg;IG!cg(tgUYkpI^qVW9LMqi32#ZBD%s+X+E$@H?j_4-F zvLLjQEl*f(WWxLt2Y5#$fE(@THJ>S>EMdx5$Uk+!a0CGum)8-CsOf*iO%Y`q8cB5Y zT>ggxGLNY>fFl-B4agc$+NLxG%s*!D44|ok29P1tfT_JI0sXJM)gmgmBAN%xorn1{fvPzR~9acguoF(k=mlI6xwGRKSh4 zqAO}lz|`loWuMH77Oa2q$?OOqSqI1P$?QlGr7c(ntZ*CVv=?qe=DT|VSV)?@>z-E` zkku{(U)BWN_wd<42OYE%GTxG8Gbu?$Y__I$^Vi!dU~+b~={qXX;~H*Kf$yDrVXc!& z4W?wf_G$a~X)5aygCgN3Ie~F%wrXuc0&t8%Ds;A6Weh;vEFOQ*#FfE#{Vx-0ULg-a zLG!I`LBr>4m|Q?&d|Yo-|Kk}-X9*@Nm!rHl&`^t(cKrVY=NQGf4Cpd z{e@tb%qg}Yl9w|=-kKI$8B+!F1bqG1Ht}p2CFueO^~;n+<$eM{2<&lyI^R%3OMEmS zwxf`}ETPGTfcAe6eh5I{hCz~4U_n#AOxd$PKA^#qEz~^%5bh7w%+}mT{8@$%3TcaV zJVS_CS847%K!J852yuvt5`$D=K}eNoWLFoxYqvw=BZbRCQifT;#u(6?Hwy?BbR{e; ztQtaLJ5RLq0xSrFRCKb50tE$G+Li@E(9Vor{>_>3&tVM?;+3ohagw}4a*4WKzW4QP8RtR7Tj1J}#} zN-W-r19XiHWkI+%q7i|@OJJo$KDvH#7L?(sDH9687ExOSbkWp+LWW03#PYkrxD^%H z!YQZ-c&jFcQ{WILyiE$vM%aJ@6hq^lse%pK(B>^lm#*QlfT;xm%tFE~YLj*b9)J6X zXj4QLX+hPOf79PVMxvW%|FHFu$fM~)pgSS)3XM!y{K>E5ZOB^?3Ko8yvS6a9h*ms; z10mcQl2N%vX2s`j<==%Ut*^V7@z{dG^>LnRh~lfjGhp_6O1O@6=`*9a$A5v327PZ4 zJ}3yngv-4bLcz8DhlCHrLAC&G=6~JS<~Q8*i7K_=a<5Ce;tfxE@PRl8%IN9_#)x)-jMB&p3o2OV_KK?hAl=w@*ar4a%QyC&hh z)A&j^K|tZZ3J{Nip@mnu1UFxxCVf2#>lcRCda8)3!Er5D3-w6*mYl;VrGKv{1cVW{ zG@wMMON%b<3)`4%K!$9X`Vx1nJYRDe`K9d1OTu6sw{{u1p*M=p8cuFIb;Gd zj=ojW^US0hH)H6hqYT=0!+&2L4ai&2&MhKlF&aMSr-4ai1R?s3(Zx-PN!K(6&^u+A zha;`oY&OTu%xva*d;9k70n@i&9#EMm3Wgv^mc>p0nxLJevm*18A?%&!jy1snxxcleylUXqnCY-pRcW zKm1t)s58i0Fjqv~IfQgYlxWtoWPG}2lF-irpt*;_n@KspV*#ry2r=wc8ks(e%EpP< z2|CLOhjd``-eO?cn}12UG$3a|=UHavfCI_euAx!iB}1Qfc{L%c~S@O zEQ{2l?yJPa&Q!uFN@Ov=+EOL+h6Y<_-zes*?# zW;XNtXZJt)=;t9|Kg=KxD3a)H3PbMnZ9`a7dM|76!WMLS4u8<~B>ptD(<4;p`oSaY z2fJCPyFm|7U?VD_6(Q`vKC1aB#3Pk?k{bknM~EDtlwM>&iU_bdJw2@jlrH|p1IEG4 z3P9z*Z3+yqgdx;CU=zjWVnAd()emQL*qnA|Gw)CypnDyJ4wnIJSwQ+hI|v{OB7Dfy z!HCfI^o5y}M1RIgE{iaIIY6S7Oups@qG0GPv~TjoVyjH%z>m%n1BJN!1zDxug@&7- z`IZ^x*TQ(Pwhc%6jU?d@7NqjxM{)U4ebl~UKd2&&52(B-Ep>iBiaUOIP$dKwbi3vUWIjha(>HXn8wrq4?1W&BD`7CQGe&@ZRceJ>LLv(Yfd8G5ygBS zVR0Jx9w^1r`q(BGC-U#UKGrx79{6zZ=@*z=G;qcL<*8;j1Hr63h5=<^uBg|FvG!~$H=gtuh z?`zpRfPbD4n13w}WnQ-Rcg-E> zZFuoZt;M593%z;dsarf+SkLgUJax0#V-tdV{J5Dtf%x0ffXT98Jpm$SygFqIN&$09 zaPWRlm;+omz^kiY|7K8ke0<-y|7WxA_)|#tfPauM_(%dq3%m6OkjN2_>37NP@IFlO z8LzZ9AE zV}PIo!8V8lbmQ@%j~Mz10A%W51z^;{2hVKF05<$+er016Sqm!Xu~hy{W~!0V6>R`a z>fomV;2#shV8@@Ti>O}>X+VrBz=lkgq<>2m056_DU%Ytn;j54F6`)!j*c!D-6e#d zZeG5;A^X8@_7@0Gb*u=AY&X#qs-cTOWrjQ{8nDX%b{4R?xv2+C>mUg@{7L0AOMmDh zP}vaz^lqDzg?W0hGVwLDzrh^dc=EE|{k7{>0rXiTwn8;@vl}zXoAMRMd_JK`U(#j4 zRKo(`rZh4jm;KTJh{_xz1^+7Fohpy7kov8w$7hBr{l6I)t3#7PAh+ z|EWV{jAxDogpw(t z6brhgY3)4(n&bqy!z^&w;`}*s@|26cP=Mv|9F7IgPx>%%Z%}s0WVR`74TORwqNTe# zvoNJuR}m)Y5ofmx3CooMVO>OK0otLGXII%}noWrF4$++qAlsDMA_`R@^T5LL)dObYk0w{G;w&hXoxPD?Cz)wVp^*U#QjLr~hT%g( z01S_*jXw&zd~){ut#B)$uLRg&Cl0pFUWDVb%Y`J3;1cminT?(r;e(9Kts>lbZ6Dp+ zOIHV1ji0zDsc`Qy4}aTn0~M-uHEi{%K!|5+>p z*cL`w+J0~it@%HHP?PkQDxw>YFK%G*%-wQXY+%8r9RnO+yX7|AfTr*Gox1D(|6Q*N z`nI6Ao&Ta4-68@hLHL*IbD z31i1Eq6Rzm0y407-G67C_4-%Vb^l)fYp-1QgLA delta 3875 zcmV+;58UwNA*djbBLV>GktK7Hq(V++SkzY>9F{OJFC>a49d5I(t}r*Q93ztu6jm`Z zHe6j`JwHThYi$An0l>h(K0Qk7>+3TxJ3&BAIont;00001bW%=J06^y0W&i*Ic#}^7 z6@NcZ!!QuV=jKyH?TCcuB#-ZuRt@7uiGu z6xmV+(V3`w_6Q3amDrMDNpLla76S|JL3YGn&Pz1)z;l&HaM~Qiu^TLHLdi1HTD}n4 z=%5R{gMC0dj6=&o*ARprO?ud}sPYF2o~YxiQYjifosmMPU_{;{sm#y^@GSa~6@PCN zgIsxV--i)#109V*SCLnzGQ7Kl2E3>Z@nI^OoO1jD17VzbVc6PxxwErlV~!sH=4cH5OfcX_@o(yUmXemOs`pW}%} zZeiB|01aqKL_t(|ob8>9cHFiRhJV?lb(i@NsY9&sg0D z-~&c|0DsQN0RDo}6o7pG%?`}5KHz6o31HrS_XAi;dQdskFj0T$0e5A{NoPU zBYi-RGy?o(Mh@^-84U##AW3C2oBzImK2!pDPZrc{T1rNQJpi*hC_v2z7K{md)WNZU z_ftd-A8^+94mhC&79(~&OeSezDy2PMJxJgc6oSL;7O-KMvQAmZ(cCCy7h?~U&nz%9;ul;30 z&3ohlC}_UX7Bqa$hRFpa#>e$WwLhMrbe2G}{iUc}mL=`kl7#VmrhIiajPAauWep6q z{@{K*_ZNa$GN;&rNM6ned24EHWlR;w6Y%w4+r+bBl%xwB)PFBi7M1%603oo)0qT51 z4K4A}fY^>g_OgT~7XsQp_#ps&8wN>Ifdx(dGG)*H_<#ma)=>8dK)63xGi!4n@n;Ah z6w(^&c!m(OuF~9jfCBAA5aJLOB|53Vf{-fF$gVDW*RH$9M+%pPqztowl`)_>Zx#?N z=t@{xST%&gb|;=_=>=F22C3*|69oziva~G=grJ=nz5JUqU zdq~9cyTP~>71+Wls0etgx>Mi~CcI4w&qmmQ0~B53o~eQr+R)}LN|&zTv4E)s0n9?e zEvl2K1|EOghiFqo6=^}$mVeXVK}MpRXFu5bNaWGhGbN(k=gUPTlse(N^9#bW<0i_aDAMoK1A_V;2AJ`oD!}h9eidK z_xLaH(V*=u!UqLGm~hy8ArxHOe@OU)*vS^4dES40ZGOW|o2XI?4trhF6|Z~BgFlF! zpp5QsKwdV#;l@eC-4Hxb3^_eouq)kk0ax=GkO#as^?TvkOOo2GTD5A`s#OaSx>=k< zX@UU5p-DLJG``X;5K#E90>q!Oa)wlRi$u`i0@Oo+_fMb6m^)LOs&HCFd|o z>EnNdfH2~g29)S@snNxq93H*^kP$dLVL)c44V2PH%34rk$}n=NiOX0z4XhYufin7#$`fXYN+C_wPIAt8QD+I%n!1IVOHaOBnA zye)qwrN()r_4xF3t2d`wX0v^K`uOwDe;or#G*A{$n@LiD_6(NLgaLC!l(AqYU08p| zJ_JyOyFyzFfUX~)6h#YifQ}F*kx@;d&3VT0oK45(**u6CKzoIDCgsU*te%{mZT03% z%WSq!&Ypbn#cv}(ok8A$xgzS$A*3s!M6;eHhgnkwP%{>&}Ov>#e3)sto5X0W5 zk!iE2Y@CRlpfgN3qywAx8UxGTOv-=3fSd)LXPKD`4qbfe{LhC(f*r{C3AR2aUL_O) z`ZFoFNgaHY19VTKTt_eL6Dc=^k^B~dRt%xEaV;n1_XtqtVPJt0wy$hwQl6h!!lxG( z+sn(#i;K$(v)Mkqc>3j+zY77|VFr0XkwkA(81hTsHiR{$_p$~rY(baj09}7i;!jgM zKS4FFA3VW+u-P=a8}tALHlh+*5yB4aqneLGJW`n_xlZsoLgWCY^dbXNM1a-#`FUSJ z>EdrZU>w}+0jT`9O@RTHFoc>1tfJUl42X>9`r&K~oAbtOwhhVybgzTZ;WB_V3rIg` z2LVJugb$fI7!lf@zA%%L$XI{LWf7(i10-6>TZ7KC^O8jhVfu^9gg&yNWvd1Nae+k;_{>VsPBsXpo%m-pz@-$)cO4=?)2e7 z;SI1+ip;>+D+FyZJ(kUDt0%v_3hVgd{FccujimvuTD59bP9rA?AHIKz)4Y#e#fkdI zuHsS)$FAOh_8H|KvNWyw)OActm+HsUdUL7M@cYwSTS?aW*7(AyA`$X z)H%ZLeJqtoFw zAZ%D;Qshs%`n}ff`SX9B-aPlz?4IweXZR1En$6~g3BkR1QEgsg{H?g`S4)718Lv&* zf>OYo5geSK64rL7=)s{P9nnn$y###{Iw9G^bzT4Ja<$=7blPDju`%lI!k$ zm*O*CXKg~58Kd`z0qx%+CcOGu>(%Y;PH%2K?Oxr!GU2DY*ROv&K=6^jEC41;@0rY1 z;D~U9^nh$=VR0M>kqmQXz=G(QjR5gah;fEPAg=zbb*mZm=4($5@aFaFzx>q+!Z_cU z5S#`)`v&80#l;g_0y_*QH**K$im)M*1$?iIw<1a?v^;2hG01{9-+mhv(Z{p}^UGg4 zMUzO@0T}1tANCRTj05)W@qyty&4lr*kslNbt_2$j)?c29+tS&Dv-|Vj5 zT$%XV&AWFue{=e~(aQ@h4S4YnjKB41WZFz{7Hq>4^xS`l0w08+>$C;F(jEM>ChX`> zPEM|O%{7Fd?%ut-Bm2Q-^G^&<_3kFBLN#;|rp%Bg#RHn=6Q=b=-!~b+#sXG%cY^`D zk5oRhgf7CA9Ra}c!6a+KfH>+&YiFKbtW12(d|zRF?aouvs%rj)@wfhuYNcxEW-sOt zSU@~}j*)+g16>wOH7o#@CC40`)j&Wl2c-cHrK~8rhZ(6UolYa)_-pP>ac>=vPi7vE z$N>S)qyGc9;XX-6q{X}LSFIYO?+W_Z`5Ue8zGrm|fP5on0Ds8nSOD214fsB*V*%tI zBn)8Af^z_lTw_rYQ3w7}5CCcW9U@>&I0P30Xgz<^&Vn9hxeg8h%r1`DIvNTi4H>{X z%6KHVoSJO^=qPe(0jVB>0>sz=b*gsuUSS#^1E~09|5ZP@#Do^Kb0Wxv=XwJ6@rmR| zW1>$crO0U@Ah)!hTYr=FO|ycCg2}wdt?O1fw_!pN{vEg_2Ncm-y7kit8w$6$Br_OR zI)s0m;})|H!~3aST!1hlZcELhuh$H?_&do(h*K5x=S_%baR#&8Kj;DhxmLqa|@ zFc8pPiUyQ6K2B09e?6ph8EJEY3S8@8Kx$BUZC4G9ytjOCXGjs{0HI_`D8+(qX=)pT z1e#0$-7H{Psa+Hg`P=J~6+%OB`1+srjBC}0tZ6GlCQPbU>S$NW{n+Ox|h_l;; zf@Amegn(@&&#t1&G^G~Mq|kshE?!8_zpJcU8`qGXsfc#boeUt`l-eQ+q2$a13(MCZ zaPLM&C_6hNzYa3fltLo|7Ni;(yAQ*Mga8=sGhH_!+)C$r0an;8M=tk-|Pj?8t>D+s={T&)%WSPGy0SkT7?7_A@q|H5(! zfFBqcz<)FP*tzc^4Vbqd0_G1s7Qn3i76bSnQY+vJcnCtk{}Ngh;NmT~c)+!Y(pmuz zKx+|Q0S{bj5nTZfTx$_s0S{bj5nUFbaiuLA@WY2i0=9la^oB0ZZP@vFE!HQ(9KXJ& l*Zo?O>wf9MmxYJV{s;WV;|;v+^z#4!002ovPDHLkV1l_JIS&8; diff --git a/tgui/packages/tgui/interfaces/NuclearBomb.js b/tgui/packages/tgui/interfaces/NuclearBomb.js index 54793d4a5380..b29bc17e0779 100644 --- a/tgui/packages/tgui/interfaces/NuclearBomb.js +++ b/tgui/packages/tgui/interfaces/NuclearBomb.js @@ -5,13 +5,22 @@ import { Window } from '../layouts'; export const NuclearBomb = (_props, context) => { const { act, data } = useBackend(context); - const cantNuke = (!data.anchor, !!data.safety); + const cantNuke = (!data.anchor, !!data.safety, !data.decryption_complete); + const cantDecrypt = (!data.anchor, data.decryption_complete); return ( - +
+ + + {data.decryption_complete + ? 'Decryption complete.' + : `Decryption time left : + ${data.decryption_time} seconds`} + + {data.timing @@ -71,6 +80,25 @@ export const NuclearBomb = (_props, context) => { /> )} + + {(!data.decrypting && ( + act('toggleEncryption')} + /> + )) || ( + act('toggleEncryption')} + /> + )} + {(!data.timing && ( Date: Tue, 20 Jun 2023 18:45:27 +0100 Subject: [PATCH 02/54] Automatic changelog for PR #3470 [ci skip] --- html/changelogs/AutoChangeLog-pr-3470.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3470.yml diff --git a/html/changelogs/AutoChangeLog-pr-3470.yml b/html/changelogs/AutoChangeLog-pr-3470.yml new file mode 100644 index 000000000000..3d4a4ce22710 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3470.yml @@ -0,0 +1,4 @@ +author: "Morrow" +delete-after: True +changes: + - rscadd: "Re-added the nuke that you can buy via intel at tier 4. Only purchasable past 120 minutes. Requires holding both groundside comms towers for authorization decryption before being able to be armed." \ No newline at end of file From 0194c8cdf161023da247b0b484f588a7a8cb6f01 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Wed, 21 Jun 2023 01:26:58 +0000 Subject: [PATCH 03/54] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-3470.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3673.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3677.yml | 5 ----- html/changelogs/archive/2023-06.yml | 11 +++++++++++ 4 files changed, 11 insertions(+), 13 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-3470.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3673.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3677.yml diff --git a/html/changelogs/AutoChangeLog-pr-3470.yml b/html/changelogs/AutoChangeLog-pr-3470.yml deleted file mode 100644 index 3d4a4ce22710..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3470.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Morrow" -delete-after: True -changes: - - rscadd: "Re-added the nuke that you can buy via intel at tier 4. Only purchasable past 120 minutes. Requires holding both groundside comms towers for authorization decryption before being able to be armed." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3673.yml b/html/changelogs/AutoChangeLog-pr-3673.yml deleted file mode 100644 index de32d1c93320..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3673.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TheGamerdk" -delete-after: True -changes: - - bugfix: "Forsaken no longer announce themselves as a distress signal" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3677.yml b/html/changelogs/AutoChangeLog-pr-3677.yml deleted file mode 100644 index ec8f3e3d1a3b..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3677.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "BeagleGaming1" -delete-after: True -changes: - - rscadd: "Melting flares makes the flares burn out faster, instead of melting like normal" - - balance: "Flares last ~10 mins, and flares in the air last ~5 mins" \ No newline at end of file diff --git a/html/changelogs/archive/2023-06.yml b/html/changelogs/archive/2023-06.yml index 1f912921a0f7..3550a9ccda17 100644 --- a/html/changelogs/archive/2023-06.yml +++ b/html/changelogs/archive/2023-06.yml @@ -294,3 +294,14 @@ - balance: Generators can no longer be blown up - balance: Bonus evolution slowly deteriorates over time when all castes are unlocked - balance: Portable Generators can now be turned off/unanchored by xeno slashes +2023-06-21: + BeagleGaming1: + - rscadd: Melting flares makes the flares burn out faster, instead of melting like + normal + - balance: Flares last ~10 mins, and flares in the air last ~5 mins + Morrow: + - rscadd: Re-added the nuke that you can buy via intel at tier 4. Only purchasable + past 120 minutes. Requires holding both groundside comms towers for authorization + decryption before being able to be armed. + TheGamerdk: + - bugfix: Forsaken no longer announce themselves as a distress signal From 1e1086d18872e5118d5873e6ad9550f4e23da042 Mon Sep 17 00:00:00 2001 From: fira Date: Wed, 21 Jun 2023 08:00:59 +0100 Subject: [PATCH 04/54] Suppresses Blood Step Signal Handler errors (#3681) While it's unneccessary to do it twice, overriding the signal handler is fine because the element can't have any other clashing logic. The problem is the Element is Attached on each Crossed and there's no real way (that i could find) to handle re-attachment of elements. In general what the whole thing tries to achieve would better be done with a Component, this problem included since they have handling of duplication. ``` runtime error: item_drop overridden. Use override = TRUE to suppress this warning proc name: stack trace (/proc/stack_trace) source file: code/__HELPERS/unsorted.dm,1815 usr: Graham Blessig (/mob/living/carbon/human) src: null usr.loc: the floor (100,72,2) (/turf/open/floor) call stack: stack trace("item_drop overridden. Use over...") /datum/element/bloody_feet (/datum/element/bloody_feet): RegisterSignal(the marine combat boots (/obj/item/clothing/shoes/marine), "item_drop", "on_shoes_removed", 0) /datum/element/bloody_feet (/datum/element/bloody_feet): Attach(Graham Blessig (/mob/living/carbon/human), 231, the marine combat boots (/obj/item/clothing/shoes/marine), 1, "#A10808") Graham Blessig (/mob/living/carbon/human): AddElement(/list (/list)) the blood (/obj/effect/decal/cleanable/blood/splatter): Crossed(Graham Blessig (/mob/living/carbon/human)) Graham Blessig (/mob/living/carbon/human): Move(the floor (100,72,2) (/turf/open/floor), 2) Graham Blessig (/mob/living/carbon/human): Move(the floor (100,72,2) (/turf/open/floor), 2) Graham Blessig (/mob/living/carbon/human): Move(the floor (100,72,2) (/turf/open/floor), 2) Graham Blessig (/mob/living/carbon/human): Move(the floor (100,72,2) (/turf/open/floor), 2) [REDACTED] (/client): Move(the floor (100,72,2) (/turf/open/floor), 2) Graham Blessig (/mob/living/carbon/human): keyLoop([REDACTED] (/client)) Input (/datum/controller/subsystem/input): fire(0) Input (/datum/controller/subsystem/input): ignite(0) Master (/datum/controller/master): RunQueue() Master (/datum/controller/master): Loop(2) Master (/datum/controller/master): StartProcessing(0) ``` --- code/datums/elements/bloody_feet.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/datums/elements/bloody_feet.dm b/code/datums/elements/bloody_feet.dm index 6a5a8a23ac6b..3bcccd8377c6 100644 --- a/code/datums/elements/bloody_feet.dm +++ b/code/datums/elements/bloody_feet.dm @@ -24,12 +24,12 @@ H.bloody_footsteps = steps_to_take LAZYADD(entered_bloody_turf, target) - RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) - RegisterSignal(target, COMSIG_HUMAN_BLOOD_CROSSED, PROC_REF(blood_crossed)) - RegisterSignal(target, COMSIG_HUMAN_CLEAR_BLOODY_FEET, PROC_REF(clear_blood)) + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved), override = TRUE) + RegisterSignal(target, COMSIG_HUMAN_BLOOD_CROSSED, PROC_REF(blood_crossed), override = TRUE) + RegisterSignal(target, COMSIG_HUMAN_CLEAR_BLOODY_FEET, PROC_REF(clear_blood), override = TRUE) if(shoes) LAZYSET(target_shoes, target, shoes) - RegisterSignal(shoes, COMSIG_ITEM_DROPPED, PROC_REF(on_shoes_removed)) + RegisterSignal(shoes, COMSIG_ITEM_DROPPED, PROC_REF(on_shoes_removed), override = TRUE) if(dry_time) addtimer(CALLBACK(src, PROC_REF(clear_blood), target), dry_time) From b4bd3ca347b9be3a7d8810b3a778844fff97cd66 Mon Sep 17 00:00:00 2001 From: sg2002 Date: Wed, 21 Jun 2023 13:29:27 +0300 Subject: [PATCH 05/54] Fix XM88 streak end notification (#3682) # About the pull request XM88 has a notification on the hit streak end, but the end user currently never sees it except for when the gun is dropped. That's because it used visible_message and those don't work with things in hand. So, you would only see it when you drop the gun. Also I've changed it so that when the gun is dropped that message only appears when there was an actual streak going. # Explain why it's good for the game REEEEE?! # Changelog :cl: sg2002 fix: XM88 now correctly notifies the user on the hit streak end. /:cl: --------- Co-authored-by: harryob --- code/modules/projectiles/guns/lever_action.dm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/code/modules/projectiles/guns/lever_action.dm b/code/modules/projectiles/guns/lever_action.dm index d611605cd0e5..259c6170ae48 100644 --- a/code/modules/projectiles/guns/lever_action.dm +++ b/code/modules/projectiles/guns/lever_action.dm @@ -71,7 +71,7 @@ their unique feature is that a direct hit will buff your damage and firerate /obj/item/weapon/gun/lever_action/dropped(mob/user) . = ..() - reset_hit_buff() + reset_hit_buff(user) addtimer(VARSET_CALLBACK(src, cur_onehand_chance, reset_onehand_chance), 4 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE) /obj/item/weapon/gun/lever_action/proc/direct_hit_buff(mob/user, mob/target, one_hand_lever = FALSE) @@ -110,7 +110,7 @@ their unique feature is that a direct hit will buff your damage and firerate if(!(flags_gun_lever_action & USES_STREAKS)) return apply_hit_buff(user, target, one_hand_lever) //this is a separate proc so it's configgable - addtimer(CALLBACK(src, PROC_REF(reset_hit_buff), one_hand_lever), hit_buff_reset_cooldown, TIMER_OVERRIDE|TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(reset_hit_buff), user, one_hand_lever), hit_buff_reset_cooldown, TIMER_OVERRIDE|TIMER_UNIQUE) /obj/item/weapon/gun/lever_action/proc/apply_hit_buff(mob/user, mob/target, one_hand_lever = FALSE) lever_sound = lever_super_sound @@ -126,7 +126,7 @@ their unique feature is that a direct hit will buff your damage and firerate fire_delay += AM.delay_mod wield_delay = 0 //for one-handed levering -/obj/item/weapon/gun/lever_action/proc/reset_hit_buff(one_hand_lever) //why does this need a user arg when it doesn't use user at all? +/obj/item/weapon/gun/lever_action/proc/reset_hit_buff(mob/user, one_hand_lever) if(!(flags_gun_lever_action & USES_STREAKS)) return SIGNAL_HANDLER @@ -513,10 +513,12 @@ their unique feature is that a direct hit will buff your damage and firerate levered = FALSE return empty_chamber(user) -/obj/item/weapon/gun/lever_action/xm88/reset_hit_buff(one_hand_lever) //why does this need a user arg when it doesn't use user at all? +/obj/item/weapon/gun/lever_action/xm88/reset_hit_buff(mob/user, one_hand_lever) if(!(flags_gun_lever_action & USES_STREAKS)) return SIGNAL_HANDLER + if(streak > 0) + to_chat(user, SPAN_WARNING("[src] beeps as it loses its targeting data, and returns to normal firing procedures.")) streak = 0 lever_sound = initial(lever_sound) lever_message = initial(lever_message) @@ -531,7 +533,6 @@ their unique feature is that a direct hit will buff your damage and firerate lever_delay = FIRE_DELAY_TIER_3 damage_mult = BASE_BULLET_DAMAGE_MULT recalculate_attachment_bonuses() //stock wield delay - visible_message(SPAN_WARNING("\The [src] beeps as it loses its targeting data, and returns to normal firing procedures."), max_distance = 1) // tell them they've lost stacks if(one_hand_lever) addtimer(VARSET_CALLBACK(src, cur_onehand_chance, reset_onehand_chance), 4 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE) From 3f7c885749061d51cb42eae9a0787a851780174f Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 21 Jun 2023 11:37:20 +0100 Subject: [PATCH 06/54] Automatic changelog for PR #3682 [ci skip] --- html/changelogs/AutoChangeLog-pr-3682.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3682.yml diff --git a/html/changelogs/AutoChangeLog-pr-3682.yml b/html/changelogs/AutoChangeLog-pr-3682.yml new file mode 100644 index 000000000000..876f0bf69928 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3682.yml @@ -0,0 +1,4 @@ +author: "sg2002" +delete-after: True +changes: + - bugfix: "XM88 now correctly notifies the user on the hit streak end." \ No newline at end of file From a329a337b809a83110b41562dd7301e542ac1265 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Wed, 21 Jun 2023 06:29:54 -0400 Subject: [PATCH 07/54] Flashlight gun attachments turn off when they should (#3669) # About the pull request This PR makes flashlight gun attachments turn off when they should. Previously, the light source was just taken away without actually turning off the light. # Explain why it's good for the game Bug/inconsistency bad # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow fix: Flashlight gun attachments turn off when they should /:cl: --- code/modules/projectiles/gun_helpers.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/projectiles/gun_helpers.dm b/code/modules/projectiles/gun_helpers.dm index 98d1be3a9c64..2cfd827b1fc2 100644 --- a/code/modules/projectiles/gun_helpers.dm +++ b/code/modules/projectiles/gun_helpers.dm @@ -167,8 +167,9 @@ As sniper rifles have both and weapon mods can change them as well. ..() deals w var/obj/item/attachable/attachment = attachments[slot] if (!attachment || !attachment.light_mod) continue - bearer.SetLuminosity(0, FALSE, src) - SetLuminosity(attachment.light_mod) + + attachment.activate_attachment(src, bearer) + return TRUE return FALSE From 62f2829574dd10b74b1bf9e554e91356af781bc6 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 21 Jun 2023 11:53:01 +0100 Subject: [PATCH 08/54] Automatic changelog for PR #3669 [ci skip] --- html/changelogs/AutoChangeLog-pr-3669.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3669.yml diff --git a/html/changelogs/AutoChangeLog-pr-3669.yml b/html/changelogs/AutoChangeLog-pr-3669.yml new file mode 100644 index 000000000000..5b2c8cc76882 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3669.yml @@ -0,0 +1,4 @@ +author: "Morrow" +delete-after: True +changes: + - bugfix: "Flashlight gun attachments turn off when they should" \ No newline at end of file From 704571b268baafefc8be898b575fb49934665574 Mon Sep 17 00:00:00 2001 From: Al-1ce <71247506+Al-1ce@users.noreply.github.com> Date: Wed, 21 Jun 2023 03:30:05 -0700 Subject: [PATCH 09/54] Adds magazines to loadouts (#3679) # About the pull request This pull request adds all of the various Boots! editions to the loadout selection. I threw in a crayon and a hubba-hubba mag because I felt like those were missing as well. # Explain why it's good for the game * Boots! is _THE_ USCM magazine. You'd expect there to be at least a dozen fanboys on the Almayer carrying an edition or two. * Crayons are sovlful. What else can I say? (I added the rainbow one instead of a dozen different colors for ease) * Hubba hubba. # Testing Photographs and Procedure Irrelevant. # Changelog :cl: add: Adds various magazines and a crayon to loadout selection. /:cl: --- code/modules/client/preferences_gear.dm | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/code/modules/client/preferences_gear.dm b/code/modules/client/preferences_gear.dm index ee8c855d8b31..1d4b77f15550 100644 --- a/code/modules/client/preferences_gear.dm +++ b/code/modules/client/preferences_gear.dm @@ -415,6 +415,33 @@ var/global/list/gear_datums_by_name = list() display_name = "Camera" path = /obj/item/device/camera +/datum/gear/toy/mags + cost = 1 + +/datum/gear/toy/mags/magazine_dirty + display_name = "Magazine" + path = /obj/item/prop/magazine/dirty + +/datum/gear/toy/mags/boots_magazine_one + display_name = "Boots Issue No.117" + path = /obj/item/prop/magazine/boots/n117 + +/datum/gear/toy/mags/boots_magazine_two + display_name = "Boots Issue No.150" + path = /obj/item/prop/magazine/boots/n150 + +/datum/gear/toy/mags/boot_magazine_three + display_name = "Boots Issue No.160" + path = /obj/item/prop/magazine/boots/n160 + +/datum/gear/toy/mags/boots_magazine_four + display_name = "Boots Issue No.54" + path = /obj/item/prop/magazine/boots/n054 + +/datum/gear/toy/mags/boots_magazine_five + display_name = "Boots Issue No.55" + path = /obj/item/prop/magazine/boots/n055 + /datum/gear/toy/film display_name = "Camera film" path = /obj/item/device/camera_film @@ -463,6 +490,10 @@ var/global/list/gear_datums_by_name = list() display_name = "Walkman" path = /obj/item/device/walkman +/datum/gear/toy/crayon + display_name = "Crayon" + path = /obj/item/toy/crayon/rainbow + /datum/gear/weapon category = "Weapons" cost = 4 From 56980a0228fc1eeafe7add81673c4f36dbc0d1a0 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 21 Jun 2023 12:10:32 +0100 Subject: [PATCH 10/54] Automatic changelog for PR #3679 [ci skip] --- html/changelogs/AutoChangeLog-pr-3679.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3679.yml diff --git a/html/changelogs/AutoChangeLog-pr-3679.yml b/html/changelogs/AutoChangeLog-pr-3679.yml new file mode 100644 index 000000000000..464c305429a9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3679.yml @@ -0,0 +1,4 @@ +author: "Al-1ce" +delete-after: True +changes: + - rscadd: "Adds various magazines and a crayon to loadout selection." \ No newline at end of file From c96ef5e816de856cfb75b900696a28576a729965 Mon Sep 17 00:00:00 2001 From: harryob Date: Wed, 21 Jun 2023 21:30:25 +0100 Subject: [PATCH 11/54] patches a href exploit --- code/game/machinery/computer/groundside_operations.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/computer/groundside_operations.dm b/code/game/machinery/computer/groundside_operations.dm index 6cefa28a2c95..9856ae8f970e 100644 --- a/code/game/machinery/computer/groundside_operations.dm +++ b/code/game/machinery/computer/groundside_operations.dm @@ -286,7 +286,7 @@ usr.RegisterSignal(cam, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/mob, reset_observer_view_on_deletion)) if("activate_echo") - var/reason = input(usr, "What is the purpose of Echo Squad?", "Activation Reason") + var/reason = strip_html(input(usr, "What is the purpose of Echo Squad?", "Activation Reason")) if(!reason) return if(alert(usr, "Confirm activation of Echo Squad for [reason]", "Confirm Activation", "Yes", "No") != "Yes") return From 608efdbd1be8daddf6c5b650089dea18ce9bed9a Mon Sep 17 00:00:00 2001 From: Drathek <76988376+Drulikar@users.noreply.github.com> Date: Wed, 21 Jun 2023 17:26:25 -0700 Subject: [PATCH 12/54] Fix Shuttle Crash Crash For Hijack (#3674) This PR fixes a crash... with shuttles crashing! Namely with this runtime on round 17377 that prevent the shuttle from launching: ``` [2023-06-19 11:33:51.878] runtime error: Cannot read null.related - proc name: get area turfs (/proc/get_area_turfs) - source file: code/__HELPERS/unsorted.dm,1251 - usr: Young Queen (/mob/living/carbon/xenomorph/queen) - src: null - usr.loc: the floor (35,50,2) (/turf/open/shuttle/dropship) - call stack: - get area turfs(/area/almayer/shipboard/brig/d... (/area/almayer/shipboard/brig/dress)) - /datum/dropship_hijack/almayer (/datum/dropship_hijack/almayer): target crash site("Upper deck Foreship") - the dropship navigation comput... (/obj/structure/machinery/computer/shuttle/dropship/flight): hijack(Young Queen (/mob/living/carbon/xenomorph/queen), 0) - the dropship navigation comput... (/obj/structure/machinery/computer/shuttle/dropship/flight): attack alien(Young Queen (/mob/living/carbon/xenomorph/queen)) - Young Queen (/mob/living/carbon/xenomorph/queen): UnarmedAttack(the dropship navigation comput... (/obj/structure/machinery/computer/shuttle/dropship/flight), 1, /list (/list), 0, 0) - Young Queen (/mob/living/carbon/xenomorph/queen): click adjacent(the dropship navigation comput... (/obj/structure/machinery/computer/shuttle/dropship/flight), null, /list (/list)) - Young Queen (/mob/living/carbon/xenomorph/queen): do click(the dropship navigation comput... (/obj/structure/machinery/computer/shuttle/dropship/flight), the floor (36,51,2) (/turf/open/shuttle/dropship), "icon-x=24;icon-y=6;left=1;butt...") - SOMEONE (/client): Click(the dropship navigation comput... (/obj/structure/machinery/computer/shuttle/dropship/flight), the floor (36,51,2) (/turf/open/shuttle/dropship), "mapwindow.map", "icon-x=24;icon-y=6;left=1;butt...") ``` # Explain why it's good for the game Not only does this fix the case of a non-existent /area/almayer/shipboard/brig/dress being selected, it will now evenly weight the possibilities of landing sites. Previously this code would favor smaller areas because an area that was 1 tile would be just as likely as an area with 20k tiles. # Testing Photographs and Procedure
Screenshots & Videos ![image](https://github.com/cmss13-devs/cmss13/assets/76988376/aa45fd06-6b8b-44b0-85b7-ff98f3038555)
# Changelog :cl: Drathek Firartix fix: Fixed a crash with hijack code possibly picking a non-existent brig area, and weighting smaller areas heavier. /:cl: --- code/modules/shuttle/dropship_hijack.dm | 90 ++++++++++++------------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/code/modules/shuttle/dropship_hijack.dm b/code/modules/shuttle/dropship_hijack.dm index 4798279a8b94..e664d0165c78 100644 --- a/code/modules/shuttle/dropship_hijack.dm +++ b/code/modules/shuttle/dropship_hijack.dm @@ -83,9 +83,7 @@ /datum/dropship_hijack/almayer/proc/target_crash_site(ship_section) target_ship_section = ship_section - var/area/target_area = get_crashsite_area(ship_section) - // spawn crash location - var/turf/target = pick(get_area_turfs(target_area)) + var/turf/target = get_crashsite_turf(ship_section) if(!target) to_chat(usr, SPAN_WARNING("No area available")) return @@ -117,9 +115,7 @@ var/list/remaining_crash_sites = almayer_ship_sections.Copy() remaining_crash_sites -= target_ship_section var/new_target_ship_section = pick(remaining_crash_sites) - var/area/target_area = get_crashsite_area(new_target_ship_section) - // spawn crash location - var/turf/target = pick(get_area_turfs(target_area)) + var/turf/target = get_crashsite_turf(new_target_ship_section) crash_site.Move(target) marine_announcement("A hostile aircraft on course for the [target_ship_section] has been successfully deterred.", "IX-50 MGAD System") target_ship_section = new_target_ship_section @@ -172,53 +168,53 @@ /datum/dropship_hijack/almayer/proc/disable_latejoin() enter_allowed = FALSE -/datum/dropship_hijack/almayer/proc/get_crashsite_area(ship_section) - var/list/areas = list() +/datum/dropship_hijack/almayer/proc/get_crashsite_turf(ship_section) + var/list/turfs = list() switch(ship_section) if("Upper deck Foreship") - areas += typesof(/area/almayer/shipboard/brig) - areas += list(/area/almayer/command/cichallway) - areas += list(/area/almayer/command/cic) + turfs += get_area_turfs(/area/almayer/shipboard/brig/armory) + turfs += get_area_turfs(/area/almayer/shipboard/brig/cells) + turfs += get_area_turfs(/area/almayer/shipboard/brig/cic_hallway) + turfs += get_area_turfs(/area/almayer/shipboard/brig/cryo) + turfs += get_area_turfs(/area/almayer/shipboard/brig/evidence_storage) + turfs += get_area_turfs(/area/almayer/shipboard/brig/execution) + turfs += get_area_turfs(/area/almayer/shipboard/brig/general_equipment) + turfs += get_area_turfs(/area/almayer/shipboard/brig/lobby) + turfs += get_area_turfs(/area/almayer/shipboard/brig/main_office) + turfs += get_area_turfs(/area/almayer/shipboard/brig/perma) + turfs += get_area_turfs(/area/almayer/shipboard/brig/processing) + turfs += get_area_turfs(/area/almayer/shipboard/brig/surgery) + turfs += get_area_turfs(/area/almayer/command/cichallway) + turfs += get_area_turfs(/area/almayer/command/cic) if("Upper deck Midship") - areas += list( - /area/almayer/medical/morgue, - /area/almayer/medical/upper_medical, - /area/almayer/medical/containment, - /area/almayer/medical/containment/cell, - /area/almayer/medical/medical_science, - /area/almayer/medical/testlab, - /area/almayer/medical/hydroponics, - ) + turfs += get_area_turfs(/area/almayer/medical/morgue) + turfs += get_area_turfs(/area/almayer/medical/upper_medical) + turfs += get_area_turfs(/area/almayer/medical/containment) + turfs += get_area_turfs(/area/almayer/medical/containment/cell) + turfs += get_area_turfs(/area/almayer/medical/medical_science) + turfs += get_area_turfs(/area/almayer/medical/testlab) + turfs += get_area_turfs(/area/almayer/medical/hydroponics) if("Upper deck Aftship") - areas += list( - /area/almayer/engineering/upper_engineering, - /area/almayer/command/computerlab, - /area/almayer/engineering/laundry, - ) + turfs += get_area_turfs(/area/almayer/engineering/upper_engineering) + turfs += get_area_turfs(/area/almayer/command/computerlab) + turfs += get_area_turfs(/area/almayer/engineering/laundry) if("Lower deck Foreship") - areas += list( - /area/almayer/hallways/hangar, - /area/almayer/hallways/vehiclehangar - ) + turfs += get_area_turfs(/area/almayer/hallways/hangar) + turfs += get_area_turfs(/area/almayer/hallways/vehiclehangar) if("Lower deck Midship") - areas += list( - /area/almayer/medical/chemistry, - /area/almayer/medical/lower_medical_lobby, - /area/almayer/medical/lockerroom, - /area/almayer/medical/lower_medical_medbay, - /area/almayer/medical/operating_room_one, - /area/almayer/medical/operating_room_two, - /area/almayer/medical/operating_room_three, - /area/almayer/medical/operating_room_four, - /area/almayer/living/briefing, - /area/almayer/squads/req, - - ) + turfs += get_area_turfs(/area/almayer/medical/chemistry) + turfs += get_area_turfs(/area/almayer/medical/lower_medical_lobby) + turfs += get_area_turfs(/area/almayer/medical/lockerroom) + turfs += get_area_turfs(/area/almayer/medical/lower_medical_medbay) + turfs += get_area_turfs(/area/almayer/medical/operating_room_one) + turfs += get_area_turfs(/area/almayer/medical/operating_room_two) + turfs += get_area_turfs(/area/almayer/medical/operating_room_three) + turfs += get_area_turfs(/area/almayer/medical/operating_room_four) + turfs += get_area_turfs(/area/almayer/living/briefing) + turfs += get_area_turfs(/area/almayer/squads/req) if("Lower deck Aftship") - areas += list( - /area/almayer/living/cryo_cells, - /area/almayer/engineering/engineering_workshop, - ) + turfs += get_area_turfs(/area/almayer/living/cryo_cells) + turfs += get_area_turfs(/area/almayer/engineering/engineering_workshop) else CRASH("Crash site [ship_section] unknown.") - return pick(areas) + return pick(turfs) From 7d54e19ef1fab3e43bbd6f369d00ea3949bf7220 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Thu, 22 Jun 2023 01:34:55 +0100 Subject: [PATCH 13/54] Automatic changelog for PR #3674 [ci skip] --- html/changelogs/AutoChangeLog-pr-3674.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3674.yml diff --git a/html/changelogs/AutoChangeLog-pr-3674.yml b/html/changelogs/AutoChangeLog-pr-3674.yml new file mode 100644 index 000000000000..34d4404e06d1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3674.yml @@ -0,0 +1,4 @@ +author: "Drathek Firartix" +delete-after: True +changes: + - bugfix: "Fixed a crash with hijack code possibly picking a non-existent brig area, and weighting smaller areas heavier." \ No newline at end of file From 4c9668053cc69df07992f2eed2d3fd64444c9279 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Thu, 22 Jun 2023 01:37:06 +0000 Subject: [PATCH 14/54] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-3669.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3674.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3679.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3682.yml | 4 ---- html/changelogs/archive/2023-06.yml | 10 ++++++++++ 5 files changed, 10 insertions(+), 16 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-3669.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3674.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3679.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3682.yml diff --git a/html/changelogs/AutoChangeLog-pr-3669.yml b/html/changelogs/AutoChangeLog-pr-3669.yml deleted file mode 100644 index 5b2c8cc76882..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3669.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Morrow" -delete-after: True -changes: - - bugfix: "Flashlight gun attachments turn off when they should" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3674.yml b/html/changelogs/AutoChangeLog-pr-3674.yml deleted file mode 100644 index 34d4404e06d1..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3674.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Drathek Firartix" -delete-after: True -changes: - - bugfix: "Fixed a crash with hijack code possibly picking a non-existent brig area, and weighting smaller areas heavier." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3679.yml b/html/changelogs/AutoChangeLog-pr-3679.yml deleted file mode 100644 index 464c305429a9..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3679.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Al-1ce" -delete-after: True -changes: - - rscadd: "Adds various magazines and a crayon to loadout selection." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3682.yml b/html/changelogs/AutoChangeLog-pr-3682.yml deleted file mode 100644 index 876f0bf69928..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3682.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "sg2002" -delete-after: True -changes: - - bugfix: "XM88 now correctly notifies the user on the hit streak end." \ No newline at end of file diff --git a/html/changelogs/archive/2023-06.yml b/html/changelogs/archive/2023-06.yml index 3550a9ccda17..53b779e0fab1 100644 --- a/html/changelogs/archive/2023-06.yml +++ b/html/changelogs/archive/2023-06.yml @@ -305,3 +305,13 @@ decryption before being able to be armed. TheGamerdk: - bugfix: Forsaken no longer announce themselves as a distress signal +2023-06-22: + Al-1ce: + - rscadd: Adds various magazines and a crayon to loadout selection. + Drathek Firartix: + - bugfix: Fixed a crash with hijack code possibly picking a non-existent brig area, + and weighting smaller areas heavier. + Morrow: + - bugfix: Flashlight gun attachments turn off when they should + sg2002: + - bugfix: XM88 now correctly notifies the user on the hit streak end. From 312760bb011412cd71f69a82879a9cf995192077 Mon Sep 17 00:00:00 2001 From: harryob Date: Thu, 22 Jun 2023 07:33:32 +0100 Subject: [PATCH 15/54] browser assets to be served via the cdn (#3683) more stuff offloaded from byond's slowness the better thank you mso https://github.com/tgstation/tgstation/pull/52681 :cl: server: server's can now support using a cdn for web assets /:cl: --- code/__HELPERS/files.dm | 5 -- code/controllers/subsystem/assets.dm | 14 +++ code/modules/admin/admin_verbs.dm | 1 + code/modules/admin/tabs/round_tab.dm | 31 +++++++ code/modules/asset_cache/asset_cache_item.dm | 6 ++ .../transports/webroot_transport.dm | 87 +++++++++++++++++++ colonialmarines.dme | 1 + config/example/resources.txt | 40 +++++++++ tools/localhost-asset-webroot-server.py | 15 ++++ 9 files changed, 195 insertions(+), 5 deletions(-) create mode 100644 code/modules/asset_cache/transports/webroot_transport.dm create mode 100644 config/example/resources.txt create mode 100644 tools/localhost-asset-webroot-server.py diff --git a/code/__HELPERS/files.dm b/code/__HELPERS/files.dm index 717a2ed5347b..f88fe7168f8d 100644 --- a/code/__HELPERS/files.dm +++ b/code/__HELPERS/files.dm @@ -12,11 +12,6 @@ return text -//Sends resource files to client cache -/client/proc/getFiles() - for(var/file in args) - src << browse_rsc(file) - /client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list(".txt",".log",".htm")) var/path = root diff --git a/code/controllers/subsystem/assets.dm b/code/controllers/subsystem/assets.dm index 283fe79cfead..38e57df93cef 100644 --- a/code/controllers/subsystem/assets.dm +++ b/code/controllers/subsystem/assets.dm @@ -7,6 +7,20 @@ SUBSYSTEM_DEF(assets) var/list/preload = list() var/datum/asset_transport/transport = new() +/datum/controller/subsystem/assets/OnConfigLoad() + var/newtransporttype = /datum/asset_transport + switch (CONFIG_GET(string/asset_transport)) + if ("webroot") + newtransporttype = /datum/asset_transport/webroot + + if (newtransporttype == transport.type) + return + + var/datum/asset_transport/newtransport = new newtransporttype () + if (newtransport.validate_config()) + transport = newtransport + transport.Load() + /datum/controller/subsystem/assets/Initialize() for(var/type in typesof(/datum/asset)) var/datum/asset/A = type diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index d21188615785..debffa9b25b0 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -176,6 +176,7 @@ var/list/admin_verbs_server = list( /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ /client/proc/cmd_debug_del_all, /datum/admins/proc/togglejoin, + /client/proc/toggle_cdn, ) var/list/admin_verbs_debug = list( diff --git a/code/modules/admin/tabs/round_tab.dm b/code/modules/admin/tabs/round_tab.dm index 980de9eed855..deb27e73f7dc 100644 --- a/code/modules/admin/tabs/round_tab.dm +++ b/code/modules/admin/tabs/round_tab.dm @@ -181,3 +181,34 @@ else to_chat(usr, "Error: Start Now: Game has already started.") return FALSE + +/client/proc/toggle_cdn() + set name = "Toggle CDN" + set category = "Server" + var/static/admin_disabled_cdn_transport = null + if(alert(usr, "Are you sure you want to toggle CDN asset transport?", "Confirm", "Yes", "No") != "Yes") + return + + var/current_transport = CONFIG_GET(string/asset_transport) + if(!current_transport || current_transport == "simple") + if(admin_disabled_cdn_transport) + CONFIG_SET(string/asset_transport, admin_disabled_cdn_transport) + admin_disabled_cdn_transport = null + SSassets.OnConfigLoad() + message_admins("[key_name_admin(usr)] re-enabled the CDN asset transport") + log_admin("[key_name(usr)] re-enabled the CDN asset transport") + return + + to_chat(usr, SPAN_ADMINNOTICE("The CDN is not enabled!")) + if(alert(usr, "CDN asset transport is not enabled! If you're having issues with assets, you can also try disabling filename mutations.", "CDN asset transport is not enabled!", "Try disabling filename mutations", "Nevermind") == "Try disabling filename mutations") + SSassets.transport.dont_mutate_filenames = !SSassets.transport.dont_mutate_filenames + message_admins("[key_name_admin(usr)] [(SSassets.transport.dont_mutate_filenames ? "disabled" : "re-enabled")] asset filename transforms.") + log_admin("[key_name(usr)] [(SSassets.transport.dont_mutate_filenames ? "disabled" : "re-enabled")] asset filename transforms.") + return + + admin_disabled_cdn_transport = current_transport + CONFIG_SET(string/asset_transport, "simple") + SSassets.OnConfigLoad() + SSassets.transport.dont_mutate_filenames = TRUE + message_admins("[key_name_admin(usr)] disabled CDN asset transport") + log_admin("[key_name(usr)] disabled CDN asset transport") diff --git a/code/modules/asset_cache/asset_cache_item.dm b/code/modules/asset_cache/asset_cache_item.dm index 52ebc7190372..72d976bf11f1 100644 --- a/code/modules/asset_cache/asset_cache_item.dm +++ b/code/modules/asset_cache/asset_cache_item.dm @@ -33,3 +33,9 @@ if (extstart) ext = ".[copytext(name, extstart+1)]" resource = file + +/datum/asset_cache_item/vv_edit_var(var_name, var_value) + return FALSE + +/datum/asset_cache_item/CanProcCall(procname) + return FALSE diff --git a/code/modules/asset_cache/transports/webroot_transport.dm b/code/modules/asset_cache/transports/webroot_transport.dm new file mode 100644 index 000000000000..e3cb33b8fabf --- /dev/null +++ b/code/modules/asset_cache/transports/webroot_transport.dm @@ -0,0 +1,87 @@ +/// CDN Webroot asset transport. +/datum/asset_transport/webroot + name = "CDN Webroot asset transport" + +/datum/asset_transport/webroot/Load() + if (validate_config(log = FALSE)) + load_existing_assets() + +/// Processes thru any assets that were registered before we were loaded as a transport. +/datum/asset_transport/webroot/proc/load_existing_assets() + for (var/asset_name in SSassets.cache) + var/datum/asset_cache_item/ACI = SSassets.cache[asset_name] + save_asset_to_webroot(ACI) + +/// Register a browser asset with the asset cache system +/// We also save it to the CDN webroot at this step instead of waiting for send_assets() +/// asset_name - the identifier of the asset +/// asset - the actual asset file or an asset_cache_item datum. +/datum/asset_transport/webroot/register_asset(asset_name, asset) + . = ..() + var/datum/asset_cache_item/ACI = . + + if (istype(ACI) && ACI.hash) + save_asset_to_webroot(ACI) + +/// Saves the asset to the webroot taking into account namespaces and hashes. +/datum/asset_transport/webroot/proc/save_asset_to_webroot(datum/asset_cache_item/ACI) + var/webroot = CONFIG_GET(string/asset_cdn_webroot) + var/newpath = "[webroot][get_asset_suffex(ACI)]" + if (fexists(newpath)) + return + if (fexists("[newpath].gz")) //its a common pattern in webhosting to save gzip'ed versions of text files and let the webserver serve them up as gzip compressed normal files, sometimes without keeping the original version. + return + return fcopy(ACI.resource, newpath) + +/// Returns a url for a given asset. +/// asset_name - Name of the asset. +/// asset_cache_item - asset cache item datum for the asset, optional, overrides asset_name +/datum/asset_transport/webroot/get_asset_url(asset_name, datum/asset_cache_item/asset_cache_item) + if (!istype(asset_cache_item)) + asset_cache_item = SSassets.cache[asset_name] + var/url = CONFIG_GET(string/asset_cdn_url) //config loading will handle making sure this ends in a / + return "[url][get_asset_suffex(asset_cache_item)]" + +/datum/asset_transport/webroot/proc/get_asset_suffex(datum/asset_cache_item/asset_cache_item) + var/base = "[copytext(asset_cache_item.hash, 1, 3)]/" + var/filename = "asset.[asset_cache_item.hash][asset_cache_item.ext]" + if (length(asset_cache_item.namespace)) + base = "namespaces/[copytext(asset_cache_item.namespace, 1, 3)]/[asset_cache_item.namespace]/" + if (!asset_cache_item.namespace_parent) + filename = "[asset_cache_item.name]" + return base + filename + + +/// webroot asset sending - does nothing unless passed legacy assets +/datum/asset_transport/webroot/send_assets(client/client, list/asset_list) + . = FALSE + var/list/legacy_assets = list() + if (!islist(asset_list)) + asset_list = list(asset_list) + for (var/asset_name in asset_list) + var/datum/asset_cache_item/ACI = asset_list[asset_name] + if (!istype(ACI)) + ACI = SSassets.cache[asset_name] + if (!ACI) + legacy_assets += asset_name //pass it on to base send_assets so it can output an error + continue + if (ACI.legacy) + legacy_assets[asset_name] = ACI + if (length(legacy_assets)) + . = ..(client, legacy_assets) + + +/// webroot slow asset sending - does nothing. +/datum/asset_transport/webroot/send_assets_slow(client/client, list/files, filerate) + return FALSE + +/datum/asset_transport/webroot/validate_config(log = TRUE) + if (!CONFIG_GET(string/asset_cdn_url)) + if (log) + log_asset("ERROR: [type]: Invalid Config: ASSET_CDN_URL") + return FALSE + if (!CONFIG_GET(string/asset_cdn_webroot)) + if (log) + log_asset("ERROR: [type]: Invalid Config: ASSET_CDN_WEBROOT") + return FALSE + return TRUE diff --git a/colonialmarines.dme b/colonialmarines.dme index 6e5bda16e73d..991c23d53bbe 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -1382,6 +1382,7 @@ #include "code\modules\asset_cache\assets\tgui.dm" #include "code\modules\asset_cache\assets\vending.dm" #include "code\modules\asset_cache\transports\asset_transport.dm" +#include "code\modules\asset_cache\transports\webroot_transport.dm" #include "code\modules\buildmode\bm-mode.dm" #include "code\modules\buildmode\buildmode.dm" #include "code\modules\buildmode\buttons.dm" diff --git a/config/example/resources.txt b/config/example/resources.txt new file mode 100644 index 000000000000..0f9aaf021aa5 --- /dev/null +++ b/config/example/resources.txt @@ -0,0 +1,40 @@ +# External resources +# Set this to the location of a .zip with the server's .rsc inside of it. +# If you set this mutiple times, the server will rotate between the links. +# To use this, the compile option PRELOAD_RSC must be set to 0 to keep byond from preloading resources +# Resource urls can not be encrypted (https://), as they are downloaded by byond, not IE, and byond can't into encryption + +EXTERNAL_RSC_URLS http://rsc.cm-ss13.com/ + + +######################## +# Browser Asset Config # +######################## +# Browser assets are any file included in interfaces. css, images, javascript, etc. +# This handles configuring how we get these to the player so interfaces can access them. + +# Asset Transport +# The normal way of getting assets to clients is to use the internal byond system. This can be slow and delay the opening of interface windows. It also doesn't allow the internal IE windows byond uses to cache anything. +# You can instead have the server save them to a website via a folder within the game server that the web server can read. This could be a simple webserver or something backed by a CDN. +# Valid values: simple, webroot. Simple is the default. +#ASSET_TRANSPORT webroot + + +# Simple asset transport configurable values. + +# Uncomment this to have the server passively send all browser assets to each client in the background. (instead of waiting for them to be needed) +# This should be uncommented in production and commented in development +#ASSET_SIMPLE_PRELOAD + + +# Webroot asset transport configurable values. + +# Local folder to save assets to. +# Assets will be saved in the format of asset.MD5HASH.EXT or in namespaces/hash/ as ASSET_FILE_NAME or asset.MD5HASH.EXT +#ASSET_CDN_WEBROOT data/asset-store/ + +# URL the folder from above can be accessed from. +# for best results the webserver powering this should return a long cache validity time, as all assets sent via this transport use hash based urls +# Encryption (https) is supported here, but linux clients will have issues if you require higher then tls 1.0. Windows clients down to windows 7 can handle tls 1.2 no issue. +# if you want to test this locally, you simpily run the `localhost-asset-webroot-server.py` python3 script to host assets stored in `data/asset-store/` via http://localhost:58715/ +#ASSET_CDN_URL http://localhost:58715/ diff --git a/tools/localhost-asset-webroot-server.py b/tools/localhost-asset-webroot-server.py new file mode 100644 index 000000000000..31a85a4eb4b5 --- /dev/null +++ b/tools/localhost-asset-webroot-server.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +from http.server import HTTPServer, SimpleHTTPRequestHandler +import os + +class CORSRequestHandler(SimpleHTTPRequestHandler): + def end_headers(self): + self.send_header('Access-Control-Allow-Origin', '*') + self.send_header('Access-Control-Allow-Methods', 'GET') + self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate') + return super(CORSRequestHandler, self).end_headers() + +os.makedirs('../data/asset-store/', exist_ok=True) +os.chdir('../data/asset-store/') +httpd = HTTPServer(('localhost', 58715), CORSRequestHandler) +httpd.serve_forever() From 80ed7b1db0978216080e70fada15926de206448d Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Thu, 22 Jun 2023 07:46:25 +0100 Subject: [PATCH 16/54] Automatic changelog for PR #3683 [ci skip] --- html/changelogs/AutoChangeLog-pr-3683.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3683.yml diff --git a/html/changelogs/AutoChangeLog-pr-3683.yml b/html/changelogs/AutoChangeLog-pr-3683.yml new file mode 100644 index 000000000000..74f16d9344af --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3683.yml @@ -0,0 +1,4 @@ +author: "harryob" +delete-after: True +changes: + - server: "server's can now support using a cdn for web assets" \ No newline at end of file From 95a20695458623bfe9d21a839ba97801315a6627 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Fri, 23 Jun 2023 01:45:52 +0000 Subject: [PATCH 17/54] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-3683.yml | 4 ---- html/changelogs/archive/2023-06.yml | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-3683.yml diff --git a/html/changelogs/AutoChangeLog-pr-3683.yml b/html/changelogs/AutoChangeLog-pr-3683.yml deleted file mode 100644 index 74f16d9344af..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3683.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "harryob" -delete-after: True -changes: - - server: "server's can now support using a cdn for web assets" \ No newline at end of file diff --git a/html/changelogs/archive/2023-06.yml b/html/changelogs/archive/2023-06.yml index 53b779e0fab1..9e9081238a2a 100644 --- a/html/changelogs/archive/2023-06.yml +++ b/html/changelogs/archive/2023-06.yml @@ -315,3 +315,6 @@ - bugfix: Flashlight gun attachments turn off when they should sg2002: - bugfix: XM88 now correctly notifies the user on the hit streak end. +2023-06-23: + harryob: + - server: server's can now support using a cdn for web assets From 907f2352f8377b12e27610c2f20be64186021e77 Mon Sep 17 00:00:00 2001 From: Drathek <76988376+Drulikar@users.noreply.github.com> Date: Thu, 22 Jun 2023 19:10:23 -0700 Subject: [PATCH 18/54] Xeno Candidate Queue (#3636) # About the pull request This PR changes it so get_alien_candidates is normally a sorted list based generally on timeofdeath in ascending order and larva spawns now pull candidates out of that list in order. That means that an observer that has yet to play, or was the first to die, and still meets all other criteria to become a larva (not AFK, has preferences set to become larva, has been dead long enough, etc.) will be chosen before others. Playing as a facehugger (dying or hugging successfully) or dying in an admin z-levels (such as thunderdome) also do not affect the value used for how you are sorted in the queue. So you should be able to freely play in either of those situations without losing your relative spot in the queue. Of course its not going to nab you out of whatever mob you are playing, but when you are a ghost again the same values will be used to sort you in the queue. Since people may enter and leave the queue each time the queue is checked, your place in the queue may go up or down. It is just a snapshot of that moment where you are. If you missed your queue message, or haven't gotten one yet, the join xeno action will now display the last message for you. # Explain why it's good for the game Picking candidates randomly is okay, but it would be more fair to give privilege to those that have been waiting longer - especially those who have yet to play. # Testing Photographs and Procedure
Screenshots & Videos Example of queen death code (since that was the most altered): ![larva](https://github.com/cmss13-devs/cmss13/assets/76988376/48211b1e-7556-4a41-879f-1dfbfabe8704)
# Changelog :cl: Drathek add: The selection to become a xeno larva is now based on timeofdeath rather than random and also sends a message to all candidates when the queue moves. Playing as a facehugger or on admin z-levels (thunderdome) will not affect your relative place in queue. The join xeno action will also display the last queue message for you when you allow xeno candidacy. fix: Fixed gibbed humans not properly setting their timeofdeath when on an admin z-level. fix: Fixed a bad del on shuttle doors when a shuttle deletes (such as intoTheSunset). /:cl: --------- Co-authored-by: harryob --- code/__DEFINES/mobs.dm | 2 - code/__DEFINES/xeno.dm | 16 +++++ code/__HELPERS/_time.dm | 4 -- code/__HELPERS/cmp.dm | 9 +++ code/__HELPERS/game.dm | 61 +++++++++++++++---- code/_onclick/observer.dm | 4 +- code/game/gamemodes/cm_initialize.dm | 36 ++++++++--- code/modules/client/client_defines.dm | 2 + .../structures/special/pylon_core.dm | 15 ++++- code/modules/mob/dead/observer/observer.dm | 19 ++++-- .../mob/living/carbon/xenomorph/Embryo.dm | 3 +- .../carbon/xenomorph/castes/Facehugger.dm | 1 + .../mob/living/carbon/xenomorph/death.dm | 18 +++--- code/modules/shuttle/helpers.dm | 3 +- code/modules/shuttle/shuttle.dm | 16 ++--- 15 files changed, 155 insertions(+), 54 deletions(-) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 495b5fb472c5..ba928e202cf0 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -11,8 +11,6 @@ #define OVEREAT_TIME 200 //================================================= -#define ALIEN_SELECT_AFK_BUFFER 1 // How many minutes that a person can be AFK before not being allowed to be an alien. - #define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point #define HEAT_DAMAGE_LEVEL_2 4 //Amount of damage applied when your body temperature passes the 400K point #define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 1000K point diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm index 6d6bd64ea918..7741beecedef 100644 --- a/code/__DEFINES/xeno.dm +++ b/code/__DEFINES/xeno.dm @@ -154,6 +154,22 @@ #define WEED_BASE_GROW_SPEED (5 SECONDS) #define WEED_BASE_DECAY_SPEED (10 SECONDS) +/// The time you must be dead to join as a xeno larva +#define XENO_JOIN_DEAD_LARVA_TIME (2.5 MINUTES) +/// The time you must be dead to join as xeno (not larva) +#define XENO_JOIN_DEAD_TIME (5 MINUTES) +/// The time of inactivity you cannot exceed to join as a xeno +#define XENO_JOIN_AFK_TIME_LIMIT (5 MINUTES) +/// The amount of time after round start before buried larva spawns are disallowed +#define XENO_BURIED_LARVA_TIME_LIMIT (30 MINUTES) + +/// The time against away_timer when an AFK xeno larva can be replaced +#define XENO_LEAVE_TIMER_LARVA 80 //80 seconds +/// The time against away_timer when an AFK xeno (not larva) can be replaced +#define XENO_LEAVE_TIMER 300 //300 seconds +/// The time against away_timer when an AFK xeno gets listed in the available list so ghosts can get ready +#define XENO_AVAILABLE_TIMER 60 //60 seconds + /// Between 2% to 10% of explosion severity #define WEED_EXPLOSION_DAMAGEMULT rand(2, 10)*0.01 diff --git a/code/__HELPERS/_time.dm b/code/__HELPERS/_time.dm index 85acafa0e2f6..b929ae8636b3 100644 --- a/code/__HELPERS/_time.dm +++ b/code/__HELPERS/_time.dm @@ -15,10 +15,6 @@ #define DECISECONDS_TO_HOURS /36000 -#define XENO_LEAVE_TIMER_LARVA 80 //80 seconds -#define XENO_LEAVE_TIMER 300 //300 seconds -#define XENO_AVAILABLE_TIMER 60 //60 seconds, when to add a xeno to the avaliable list so ghosts can get ready - var/midnight_rollovers = 0 var/rollovercheck_last_timeofday = 0 diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 4ca0edcf43d0..888e3c2ce657 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -57,3 +57,12 @@ var/atom/cmp_dist_origin=null /proc/cmp_typepaths_asc(A, B) return sorttext("[B]","[A]") + +/// Compares mobs based on their timeofdeath value in ascending order +/proc/cmp_mob_deathtime_asc(mob/A, mob/B) + return A.timeofdeath - B.timeofdeath + +/// Compares observers based on their larva_queue_time value in ascending order +/// Assumes the client on the observer is not null +/proc/cmp_obs_larvaqueuetime_asc(mob/dead/observer/A, mob/dead/observer/B) + return A.client.larva_queue_time - B.client.larva_queue_time diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index a0bb9dd98423..61976f4dc903 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -241,35 +241,70 @@ else return get_step(start, EAST) -// Same as above but for alien candidates. -/proc/get_alien_candidates() +/// Get a list of observers that can be alien candidates, optionally sorted by larva_queue_time +/proc/get_alien_candidates(sorted = TRUE) var/list/candidates = list() - for(var/i in GLOB.observer_list) - var/mob/dead/observer/O = i + for(var/mob/dead/observer/cur_obs as anything in GLOB.observer_list) + // Preference check + if(!cur_obs.client || !cur_obs.client.prefs || !(cur_obs.client.prefs.be_special & BE_ALIEN_AFTER_DEATH)) + continue + // Jobban check - if(!O.client || !O.client.prefs || !(O.client.prefs.be_special & BE_ALIEN_AFTER_DEATH) || jobban_isbanned(O, JOB_XENOMORPH)) + if(jobban_isbanned(cur_obs, JOB_XENOMORPH)) continue //players that can still be revived are skipped - if(O.mind && O.mind.original && ishuman(O.mind.original)) - var/mob/living/carbon/human/H = O.mind.original - if (H.check_tod() && H.is_revivable()) + if(cur_obs.mind && cur_obs.mind.original && ishuman(cur_obs.mind.original)) + var/mob/living/carbon/human/cur_human = cur_obs.mind.original + if(cur_human.check_tod() && cur_human.is_revivable()) continue // copied from join as xeno - var/deathtime = world.time - O.timeofdeath - if(deathtime < 3000 && ( !O.client.admin_holder || !(O.client.admin_holder.rights & R_ADMIN)) ) + var/deathtime = world.time - cur_obs.timeofdeath + if(deathtime < XENO_JOIN_DEAD_TIME && ( !cur_obs.client.admin_holder || !(cur_obs.client.admin_holder.rights & R_ADMIN)) ) continue - // Admins and AFK players cannot be drafted - if(O.client.inactivity / 600 > ALIEN_SELECT_AFK_BUFFER + 5 || (O.client.admin_holder && (O.client.admin_holder.rights & R_MOD)) && O.adminlarva == 0) + // AFK players cannot be drafted + if(cur_obs.client.inactivity > XENO_JOIN_AFK_TIME_LIMIT) continue - candidates += O + // Mods with larva protection cannot be drafted + if((cur_obs.client.admin_holder && (cur_obs.client.admin_holder.rights & R_MOD)) && !cur_obs.adminlarva) + continue + + candidates += cur_obs + + // Optionally sort by larva_queue_time + if(sorted && length(candidates)) + candidates = sort_list(candidates, GLOBAL_PROC_REF(cmp_obs_larvaqueuetime_asc)) return candidates +/** + * Messages observers that are currently candidates an update on the queue. + * + * Arguments: + * * candidates - The list of observers from get_alien_candidates() + * * dequeued - How many candidates to skip messaging because they were dequeued + * * cache_only - Whether to not actually send a to_chat message and instead only update larva_queue_cached_message + */ +/proc/message_alien_candidates(list/candidates, dequeued, cache_only = FALSE) + var/new_players = 0 + for(var/i in (1 + dequeued) to candidates.len) + var/mob/dead/observer/cur_obs = candidates[i] + + // Generate the messages + var/cached_message = SPAN_XENONOTICE("You are currently [i-dequeued]\th in the larva queue. There are [new_players] ahead of you that have yet to play this round.") + cur_obs.larva_queue_cached_message = cached_message + if(!cache_only) + var/chat_message = dequeued ? replacetext(cached_message, "currently", "now") : cached_message + to_chat(candidates[i], chat_message) + + // Count how many are prioritized + if(cur_obs.client.larva_queue_time < 2) // 0 and 1 because facehuggers/t-domers are slightly deprioritized + new_players++ + /proc/convert_k2c(temp) return ((temp - T0C)) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 21ac66e5f222..5acfe74f2965 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -45,11 +45,11 @@ return FALSE var/deathtime = world.time - timeofdeath - if(deathtime < 2.5 MINUTES) + if(deathtime < XENO_JOIN_DEAD_LARVA_TIME) var/message = "You have been dead for [DisplayTimeText(deathtime)]." message = SPAN_WARNING("[message]") to_chat(src, message) - to_chat(src, SPAN_WARNING("You must wait 2.5 minutes before rejoining the game!")) + to_chat(src, SPAN_WARNING("You must wait atleast 2.5 minutes before rejoining the game!")) ManualFollow(target) return FALSE diff --git a/code/game/gamemodes/cm_initialize.dm b/code/game/gamemodes/cm_initialize.dm index 8237fc63b7e2..2f6dc6e38118 100644 --- a/code/game/gamemodes/cm_initialize.dm +++ b/code/game/gamemodes/cm_initialize.dm @@ -354,7 +354,7 @@ Additional game mode variables. var/datum/hive_status/hive for(var/hivenumber in GLOB.hive_datum) hive = GLOB.hive_datum[hivenumber] - if(!hive.hardcore && hive.stored_larva && (hive.hive_location || (world.time < 30 MINUTES + SSticker.round_start_time))) + if(!hive.hardcore && hive.stored_larva && (hive.hive_location || (world.time < XENO_BURIED_LARVA_TIME_LIMIT + SSticker.round_start_time))) if(SSticker.mode && (SSticker.mode.flags_round_type & MODE_RANDOM_HIVE)) available_xenos |= "any buried larva" LAZYADD(available_xenos["any buried larva"], hive) @@ -364,7 +364,27 @@ Additional game mode variables. available_xenos[larva_option] = list(hive) if(!available_xenos.len || (instant_join && !available_xenos_non_ssd.len)) - to_chat(xeno_candidate, SPAN_WARNING("There aren't any available xenomorphs or burrowed larvae. You can try getting spawned as a chestburster larva by toggling your Xenomorph candidacy in Preferences -> Toggle SpecialRole Candidacy.")) + if(!xeno_candidate.client || !xeno_candidate.client.prefs || !(xeno_candidate.client.prefs.be_special & BE_ALIEN_AFTER_DEATH)) + to_chat(xeno_candidate, SPAN_WARNING("There aren't any available xenomorphs or burrowed larvae. You can try getting spawned as a chestburster larva by toggling your Xenomorph candidacy in Preferences -> Toggle SpecialRole Candidacy.")) + return FALSE + to_chat(xeno_candidate, SPAN_WARNING("There aren't any available xenomorphs or burrowed larvae.")) + + // Give the player a cached message of their queue status if they are an observer + var/mob/dead/observer/candidate_observer = xeno_candidate + if(istype(candidate_observer)) + if(candidate_observer.larva_queue_cached_message) + to_chat(xeno_candidate, candidate_observer.larva_queue_cached_message) + return FALSE + + // No cache, lets check now then + message_alien_candidates(get_alien_candidates(), dequeued = 0, cache_only = TRUE) + if(candidate_observer.larva_queue_cached_message) + to_chat(xeno_candidate, candidate_observer.larva_queue_cached_message) + return FALSE + + // We aren't in queue yet, lets teach them about the queue then + candidate_observer.larva_queue_cached_message = SPAN_XENONOTICE("You are currently still awaiting assignment in the larva queue. Priority is given to players who have yet to play in the round, but otherwise the ordering is based on your time of death. When you have been dead long enough and are not inactive, you will periodically receive messages where you are in the queue relative to other currently valid xeno candidates. Note: Playing as a facehugger or in the thunderdome will not alter your time of death. This means you won't lose your relative place in queue if you step away, disconnect, play as a facehugger, or play in the thunderdome.") + to_chat(xeno_candidate, candidate_observer.larva_queue_cached_message) return FALSE var/mob/living/carbon/xenomorph/new_xeno @@ -377,11 +397,11 @@ Additional game mode variables. if(!xeno_bypass_timer) var/deathtime = world.time - xeno_candidate.timeofdeath if(isnewplayer(xeno_candidate)) - deathtime = 2.5 MINUTES //so new players don't have to wait to latejoin as xeno in the round's first 5 mins. - if(deathtime < 2.5 MINUTES && !check_client_rights(xeno_candidate.client, R_ADMIN, FALSE)) + deathtime = XENO_JOIN_DEAD_LARVA_TIME //so new players don't have to wait to latejoin as xeno in the round's first 5 mins. + if(deathtime < XENO_JOIN_DEAD_LARVA_TIME && !check_client_rights(xeno_candidate.client, R_ADMIN, FALSE)) var/message = SPAN_WARNING("You have been dead for [DisplayTimeText(deathtime)].") to_chat(xeno_candidate, message) - to_chat(xeno_candidate, SPAN_WARNING("You must wait 2.5 minutes before rejoining the game as a buried larva!")) + to_chat(xeno_candidate, SPAN_WARNING("You must wait 2 minutes and 30 seconds before rejoining the game as a buried larva!")) return FALSE for(var/mob_name in picked_hive.banished_ckeys) @@ -393,7 +413,7 @@ Additional game mode variables. noob.close_spawn_windows() if(picked_hive.hive_location) picked_hive.hive_location.spawn_burrowed_larva(xeno_candidate) - else if((world.time < 30 MINUTES + SSticker.round_start_time)) + else if((world.time < XENO_BURIED_LARVA_TIME_LIMIT + SSticker.round_start_time)) picked_hive.do_buried_larva_spawn(xeno_candidate) else to_chat(xeno_candidate, SPAN_WARNING("Seems like something went wrong. Try again?")) @@ -417,8 +437,8 @@ Additional game mode variables. if(!xeno_bypass_timer) var/deathtime = world.time - xeno_candidate.timeofdeath if(istype(xeno_candidate, /mob/new_player)) - deathtime = 5 MINUTES //so new players don't have to wait to latejoin as xeno in the round's first 5 mins. - if(deathtime < 5 MINUTES && !check_client_rights(xeno_candidate.client, R_ADMIN, FALSE)) + deathtime = XENO_JOIN_DEAD_TIME //so new players don't have to wait to latejoin as xeno in the round's first 5 mins. + if(deathtime < XENO_JOIN_DEAD_TIME && !check_client_rights(xeno_candidate.client, R_ADMIN, FALSE)) var/message = "You have been dead for [DisplayTimeText(deathtime)]." message = SPAN_WARNING("[message]") to_chat(xeno_candidate, message) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 8f0939474427..fbec4aa13f36 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -26,6 +26,8 @@ var/adminobs = null var/area = null var/time_died_as_mouse = null //when the client last died as a mouse + /// The descriminator for larva queue ordering: Generally set to timeofdeath except for facehuggers/admin z-level play + var/larva_queue_time var/donator = 0 var/adminhelped = 0 diff --git a/code/modules/cm_aliens/structures/special/pylon_core.dm b/code/modules/cm_aliens/structures/special/pylon_core.dm index 9376e2b6e914..08aa2f86c1bc 100644 --- a/code/modules/cm_aliens/structures/special/pylon_core.dm +++ b/code/modules/cm_aliens/structures/special/pylon_core.dm @@ -108,6 +108,7 @@ var/last_healed = 0 var/last_attempt = 0 // logs time of last attempt to prevent spam. if you want to destroy it, you must commit. var/last_larva_time = 0 + var/last_larva_queue_time = 0 var/last_surge_time = 0 var/spawn_cooldown = 30 SECONDS var/surge_cooldown = 90 SECONDS @@ -142,11 +143,19 @@ linked_hive.hive_ui.update_burrowed_larva() qdel(L) - if((last_larva_time + spawn_cooldown) < world.time && can_spawn_larva()) // every minute + var/spawning_larva = can_spawn_larva() && (last_larva_time + spawn_cooldown) < world.time + if(spawning_larva) last_larva_time = world.time + if(spawning_larva || (last_larva_queue_time + spawn_cooldown * 4) < world.time) + last_larva_queue_time = world.time var/list/players_with_xeno_pref = get_alien_candidates() - if(players_with_xeno_pref && players_with_xeno_pref.len && can_spawn_larva()) - spawn_burrowed_larva(pick(players_with_xeno_pref)) + if(players_with_xeno_pref && players_with_xeno_pref.len) + if(spawning_larva && spawn_burrowed_larva(players_with_xeno_pref[1])) + // We were in spawning_larva mode and successfully spawned someone + message_alien_candidates(players_with_xeno_pref, dequeued = 1) + else + // Just time to update everyone their queue status (or the spawn failed) + message_alien_candidates(players_with_xeno_pref, dequeued = 0) if(linked_hive.hijack_burrowed_surge && (last_surge_time + surge_cooldown) < world.time) last_surge_time = world.time diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 47e747d4cd5c..fcb95a6fd783 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -33,8 +33,8 @@ plane = GHOST_PLANE layer = ABOVE_FLY_LAYER stat = DEAD - var/adminlarva = 0 - var/ghostvision = 1 + var/adminlarva = FALSE + var/ghostvision = TRUE var/can_reenter_corpse var/started_as_observer //This variable is set to 1 when you enter the game as an observer. //If you died in the game and are a ghost - this will remain as null. @@ -45,7 +45,7 @@ "Squad HUD" = FALSE, "Xeno Status HUD" = FALSE ) - universal_speak = 1 + universal_speak = TRUE var/updatedir = TRUE //Do we have to update our dir as the ghost moves around? var/atom/movable/following = null var/datum/orbit_menu/orbit_menu @@ -55,6 +55,8 @@ var/own_orbit_size = 0 var/observer_actions = list(/datum/action/observer_action/join_xeno) var/datum/action/minimap/observer/minimap + var/larva_queue_cached_message + alpha = 127 /mob/dead/observer/verb/toggle_ghostsee() @@ -327,8 +329,8 @@ Works together with spawning an observer, noted above. ghost.langchat_make_image() SStgui.on_transfer(src, ghost) - if(is_admin_level(z)) - ghost.timeofdeath = 0 // Bypass respawn limit if you die on the admin zlevel + if(is_admin_level((get_turf(src))?.z)) // Gibbed humans ghostize the brain in their head which itself is z 0 + ghost.timeofdeath = 1 // Bypass respawn limit if you die on the admin zlevel ghost.key = key ghost.mind = mind @@ -363,6 +365,12 @@ Works together with spawning an observer, noted above. if(ghost.client.player_data) ghost.client.player_data.load_timestat_data() + // Larva queue: We use the larger of their existing queue time or the new timeofdeath except for facehuggers + // We don't change facehugger timeofdeath because they are still on cooldown if they died as a hugger + // Facehuggers are atleast 1 because they did get some action compared to those at 0 timeofdeath + var/new_tod = isfacehugger(src) ? 1 : ghost.timeofdeath + ghost.client.larva_queue_time = max(ghost.client.larva_queue_time, new_tod) + ghost.set_huds_from_prefs() return ghost @@ -405,6 +413,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/mob/dead/observer/ghost = ghostize((is_nested && nest && !QDELETED(nest))) //FALSE parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3 if(ghost && !is_admin_level(z)) ghost.timeofdeath = world.time + ghost.client?.larva_queue_time = world.time if(is_nested && nest && !QDELETED(nest)) ghost.can_reenter_corpse = FALSE nest.ghost_of_buckled_mob = ghost diff --git a/code/modules/mob/living/carbon/xenomorph/Embryo.dm b/code/modules/mob/living/carbon/xenomorph/Embryo.dm index e03f225ccade..a74c82026dbe 100644 --- a/code/modules/mob/living/carbon/xenomorph/Embryo.dm +++ b/code/modules/mob/living/carbon/xenomorph/Embryo.dm @@ -157,7 +157,8 @@ var/list/candidates = get_alien_candidates() if(candidates && candidates.len) - picked = pick(candidates) + picked = candidates[1] + message_alien_candidates(candidates, dequeued = 1) // Spawn the larva var/mob/living/carbon/xenomorph/larva/new_xeno diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm index d9ab8a1e849d..c0b57af9d3db 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm @@ -155,6 +155,7 @@ for(var/mob/dead/observer/observer as anything in GLOB.observer_list) to_chat(observer, SPAN_DEADSAY("[human] has been facehugged by [src]" + " [OBSERVER_JMP(observer, human)]")) to_chat(src, SPAN_DEADSAY("[human] has been facehugged by [src]")) + timeofdeath = 1 // Ever so slightly deprioritized for larva queue qdel(src) if(hug_area) xeno_message(SPAN_XENOMINORWARNING("You sense that [src] has facehugged a host at \the [hug_area]!"), 1, src.hivenumber) diff --git a/code/modules/mob/living/carbon/xenomorph/death.dm b/code/modules/mob/living/carbon/xenomorph/death.dm index ce3f55700753..f3534318f673 100644 --- a/code/modules/mob/living/carbon/xenomorph/death.dm +++ b/code/modules/mob/living/carbon/xenomorph/death.dm @@ -37,12 +37,13 @@ if(GLOB.hive_datum[hivenumber].stored_larva) GLOB.hive_datum[hivenumber].stored_larva = round(GLOB.hive_datum[hivenumber].stored_larva * 0.5) //Lose half on dead queen - var/turf/larva_spawn + var/list/players_with_xeno_pref = get_alien_candidates() - while(GLOB.hive_datum[hivenumber].stored_larva > 0 && istype(GLOB.hive_datum[hivenumber].hive_location, /obj/effect/alien/resin/special/pylon/core)) // stil some left - larva_spawn = get_turf(GLOB.hive_datum[hivenumber].hive_location) - if(players_with_xeno_pref && players_with_xeno_pref.len) - var/mob/xeno_candidate = pick(players_with_xeno_pref) + if(players_with_xeno_pref && istype(GLOB.hive_datum[hivenumber].hive_location, /obj/effect/alien/resin/special/pylon/core)) + var/turf/larva_spawn = get_turf(GLOB.hive_datum[hivenumber].hive_location) + var/count = 0 + while(GLOB.hive_datum[hivenumber].stored_larva > 0 && count < length(players_with_xeno_pref)) // still some left + var/mob/xeno_candidate = players_with_xeno_pref[++count] var/mob/living/carbon/xenomorph/larva/new_xeno = new /mob/living/carbon/xenomorph/larva(larva_spawn) new_xeno.set_hive_and_update(hivenumber) @@ -50,11 +51,14 @@ if(!SSticker.mode.transfer_xeno(xeno_candidate, new_xeno)) qdel(new_xeno) return + new_xeno.visible_message(SPAN_XENODANGER("A larva suddenly burrows out of the ground!"), SPAN_XENODANGER("You burrow out of the ground after feeling an immense tremor through the hive, which quickly fades into complete silence...")) - GLOB.hive_datum[hivenumber].stored_larva-- - GLOB.hive_datum[hivenumber].hive_ui.update_burrowed_larva() + GLOB.hive_datum[hivenumber].stored_larva-- + GLOB.hive_datum[hivenumber].hive_ui.update_burrowed_larva() + if(count) + message_alien_candidates(players_with_xeno_pref, dequeued = count) if(hive && hive.living_xeno_queen == src) xeno_message(SPAN_XENOANNOUNCE("A sudden tremor ripples through the hive... the Queen has been slain! Vengeance!"),3, hivenumber) diff --git a/code/modules/shuttle/helpers.dm b/code/modules/shuttle/helpers.dm index 14cfcc3cd691..1d841581faa0 100644 --- a/code/modules/shuttle/helpers.dm +++ b/code/modules/shuttle/helpers.dm @@ -8,7 +8,8 @@ /datum/door_controller/aggregate/Destroy(force, ...) . = ..() - QDEL_NULL_LIST(door_controllers) + QDEL_LIST_ASSOC_VAL(door_controllers) + door_controllers = null /datum/door_controller/aggregate/proc/set_label(label) for(var/datum/door_controller/single/cont in door_controllers) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 77ba9681ebb6..7e181ed470cb 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -628,15 +628,15 @@ /obj/docking_port/mobile/proc/intoTheSunset() // Loop over mobs - for(var/t in return_turfs()) - var/turf/T = t - for(var/mob/living/L in T.GetAllContents()) + for(var/turf/turf as anything in return_turfs()) + for(var/mob/living/mob in turf.GetAllContents()) // Ghostize them and put them in nullspace stasis (for stat & possession checks) - //L.notransform = TRUE - var/mob/dead/observer/O = L.ghostize(FALSE) - if(O) - O.timeofdeath = world.time - L.moveToNullspace() + //mob.notransform = TRUE + var/mob/dead/observer/obs = mob.ghostize(FALSE) + if(obs) + obs.timeofdeath = world.time + obs.client?.larva_queue_time = world.time + mob.moveToNullspace() // Now that mobs are stowed, delete the shuttle jumpToNullSpace() From 2d9c4526bf4ffe45c5d8ad72493c83b0a2d18371 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 23 Jun 2023 03:19:01 +0100 Subject: [PATCH 19/54] Automatic changelog for PR #3636 [ci skip] --- html/changelogs/AutoChangeLog-pr-3636.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3636.yml diff --git a/html/changelogs/AutoChangeLog-pr-3636.yml b/html/changelogs/AutoChangeLog-pr-3636.yml new file mode 100644 index 000000000000..a1dcf5fbeb71 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3636.yml @@ -0,0 +1,6 @@ +author: "Drathek" +delete-after: True +changes: + - rscadd: "The selection to become a xeno larva is now based on timeofdeath rather than random and also sends a message to all candidates when the queue moves. Playing as a facehugger or on admin z-levels (thunderdome) will not affect your relative place in queue. The join xeno action will also display the last queue message for you when you allow xeno candidacy." + - bugfix: "Fixed gibbed humans not properly setting their timeofdeath when on an admin z-level." + - bugfix: "Fixed a bad del on shuttle doors when a shuttle deletes (such as intoTheSunset)." \ No newline at end of file From 84252782a8eb1e45987d81945b67bfd7dad1f2bd Mon Sep 17 00:00:00 2001 From: Cursor <102828457+theselfish@users.noreply.github.com> Date: Fri, 23 Jun 2023 07:59:10 +0100 Subject: [PATCH 20/54] Adds the Corpsman Helmet to Req (#3692) # About the pull request Wanna know what the rarest marine helmet is? Basic grunt, squad level I mean. The Medic helmet. Can't get it from Req, or nothing. And most folks dump them anyway because they wanna drop their flags. # Explain why it's good for the game If you want to replace it, it's near impossible. If you wanna deploy as a FOB Surgeon you have to stick with a grunt helmet. This makes that better. It, as before has the exact same stats and usage as a regular helmet. If we can give tech helmets to everyone (don't get me started) then we should be able to give red crosses to everyone. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: qol: Added the Corpsman Helmet to Req's surplus vendor. /:cl: --- code/game/machinery/vending/vendor_types/requisitions.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/machinery/vending/vendor_types/requisitions.dm b/code/game/machinery/vending/vendor_types/requisitions.dm index 250a998f38bf..838b21a00e6f 100644 --- a/code/game/machinery/vending/vendor_types/requisitions.dm +++ b/code/game/machinery/vending/vendor_types/requisitions.dm @@ -426,6 +426,7 @@ list("ARMOR", -1, null, null), list("M10 Pattern Marine Helmet", 20, /obj/item/clothing/head/helmet/marine, VENDOR_ITEM_REGULAR), list("M10 Pattern Technician Helmet", 20, /obj/item/clothing/head/helmet/marine/tech, VENDOR_ITEM_REGULAR), + list("M10 Pattern Corpman Helmet", 20, /obj/item/clothing/head/helmet/marine/medic, VENDOR_ITEM_REGULAR), list("M3 Pattern Carrier Marine Armor", 20, /obj/item/clothing/suit/storage/marine/carrier, VENDOR_ITEM_REGULAR), list("M3 Pattern Padded Marine Armor", 20, /obj/item/clothing/suit/storage/marine/padded, VENDOR_ITEM_REGULAR), list("M3 Pattern Padless Marine Armor", 20, /obj/item/clothing/suit/storage/marine/padless, VENDOR_ITEM_REGULAR), From e4b50ad01bccbad4dd6f1bba31af53807c2b64f4 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 23 Jun 2023 08:12:27 +0100 Subject: [PATCH 21/54] Automatic changelog for PR #3692 [ci skip] --- html/changelogs/AutoChangeLog-pr-3692.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3692.yml diff --git a/html/changelogs/AutoChangeLog-pr-3692.yml b/html/changelogs/AutoChangeLog-pr-3692.yml new file mode 100644 index 000000000000..cf20a4947af4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3692.yml @@ -0,0 +1,4 @@ +author: "theselfish" +delete-after: True +changes: + - qol: "Added the Corpsman Helmet to Req's surplus vendor." \ No newline at end of file From 89baad17a584cdfadac861abba63a21443b0fc11 Mon Sep 17 00:00:00 2001 From: forest2001 <41653574+realforest2001@users.noreply.github.com> Date: Fri, 23 Jun 2023 08:03:04 +0100 Subject: [PATCH 22/54] Logging Improvements (#3652) # About the pull request Makes admin deadchat logs clearer # Explain why it's good for the game Logs being confusing isn't good # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: admin: Improves logging for admin deadchat. admin: Adds logging for xeno evolution. /:cl: --- code/modules/admin/verbs/deadsay.dm | 2 +- code/modules/mob/living/carbon/xenomorph/Evolution.dm | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm index be8a5693df6e..700d42808a07 100644 --- a/code/modules/admin/verbs/deadsay.dm +++ b/code/modules/admin/verbs/deadsay.dm @@ -23,7 +23,7 @@ stafftype = "[admin_holder.rank]" msg = strip_html(msg) - log_admin("[key_name(src)] : [msg]") + log_admin("DEAD: [key_name(src)] : [msg]") if (!msg) return diff --git a/code/modules/mob/living/carbon/xenomorph/Evolution.dm b/code/modules/mob/living/carbon/xenomorph/Evolution.dm index 1f88643db764..4806f7528582 100644 --- a/code/modules/mob/living/carbon/xenomorph/Evolution.dm +++ b/code/modules/mob/living/carbon/xenomorph/Evolution.dm @@ -140,6 +140,7 @@ if(3) hive.tier_3_xenos |= new_xeno + log_game("EVOLVE: [key_name(src)] evolved into [new_xeno].") if(mind) mind.transfer_to(new_xeno) else @@ -327,6 +328,7 @@ qdel(new_xeno) return + log_game("EVOLVE: [key_name(src)] de-evolved into [new_xeno].") if(mind) mind.transfer_to(new_xeno) else From cc7a9099bc2dbe6c1807080d66c9fdb4d28d7cbc Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 23 Jun 2023 08:26:49 +0100 Subject: [PATCH 23/54] Automatic changelog for PR #3652 [ci skip] --- html/changelogs/AutoChangeLog-pr-3652.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3652.yml diff --git a/html/changelogs/AutoChangeLog-pr-3652.yml b/html/changelogs/AutoChangeLog-pr-3652.yml new file mode 100644 index 000000000000..d95df39d8567 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3652.yml @@ -0,0 +1,5 @@ +author: "realforest2001" +delete-after: True +changes: + - admin: "Improves logging for admin deadchat." + - admin: "Adds logging for xeno evolution." \ No newline at end of file From f994b37c622bd40bab67fb44128fda4c89efbb48 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Fri, 23 Jun 2023 13:01:56 -0400 Subject: [PATCH 24/54] Fixes gun light attachment issues (#3696) # About the pull request Remember, when you move an object around you drop it. Fun. This PR should fix two things: Lights not being disconnected from a mob and back to the gun when dropping a gun with a light. Light attachments turning off when moving a weapon around. Uuuuh my bad. Somehow missed this in testing. # Explain why it's good for the game Bugs bad. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow fix: Fixed two gun light attachment issues /:cl: --- code/modules/projectiles/gun_helpers.dm | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/code/modules/projectiles/gun_helpers.dm b/code/modules/projectiles/gun_helpers.dm index 2cfd827b1fc2..d8ea29cd92f8 100644 --- a/code/modules/projectiles/gun_helpers.dm +++ b/code/modules/projectiles/gun_helpers.dm @@ -143,7 +143,7 @@ As sniper rifles have both and weapon mods can change them as well. ..() deals w /obj/item/weapon/gun/dropped(mob/user) . = ..() - turn_off_light(user) + disconnect_light_from_mob(user) var/delay_left = (last_fired + fire_delay + additional_fire_group_delay) - world.time if(fire_delay_group && delay_left > 0) @@ -160,16 +160,28 @@ As sniper rifles have both and weapon mods can change them as well. ..() deals w for(var/group in fire_delay_group) LAZYSET(user.fire_delay_next_fire, group, world.time + delay_left) -/obj/item/weapon/gun/proc/turn_off_light(mob/bearer) +/// This function disconnects the luminosity from the mob and back to the gun +/obj/item/weapon/gun/proc/disconnect_light_from_mob(mob/bearer) if (!(flags_gun_features & GUN_FLASHLIGHT_ON)) return FALSE for (var/slot in attachments) var/obj/item/attachable/attachment = attachments[slot] if (!attachment || !attachment.light_mod) continue + bearer.SetLuminosity(0, FALSE, src) + SetLuminosity(attachment.light_mod) + return TRUE + return FALSE +/// This function actually turns the lights on the gun off +/obj/item/weapon/gun/proc/turn_off_light(mob/bearer) + if (!(flags_gun_features & GUN_FLASHLIGHT_ON)) + return FALSE + for (var/slot in attachments) + var/obj/item/attachable/attachment = attachments[slot] + if (!attachment || !attachment.light_mod) + continue attachment.activate_attachment(src, bearer) - return TRUE return FALSE From 902e7cd1e9bde157c6cc84580fe7fb099dc22b86 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 23 Jun 2023 18:10:45 +0100 Subject: [PATCH 25/54] Automatic changelog for PR #3696 [ci skip] --- html/changelogs/AutoChangeLog-pr-3696.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3696.yml diff --git a/html/changelogs/AutoChangeLog-pr-3696.yml b/html/changelogs/AutoChangeLog-pr-3696.yml new file mode 100644 index 000000000000..dabfba255741 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3696.yml @@ -0,0 +1,4 @@ +author: "Morrow" +delete-after: True +changes: + - bugfix: "Fixed two gun light attachment issues" \ No newline at end of file From 3aa4f199eca4870c681b66406726cc78bff0b983 Mon Sep 17 00:00:00 2001 From: Drathek <76988376+Drulikar@users.noreply.github.com> Date: Fri, 23 Jun 2023 10:07:04 -0700 Subject: [PATCH 26/54] Fix erronous flamer_tank is empty messages and add sfx to empty canister verb (#3623) # About the pull request This PR is a followup to #3357 to fix an incorrect message discovered when reviewing that PR as well as to make the existing empty_reagents verb behave the same as the empty_reagents verb added in that PR. # Explain why it's good for the game The messages sent to the user should be accurate, and verbs should have consistent behavior. # Testing Photographs and Procedure
Screenshots & Videos [Refill](https://github.com/cmss13-devs/cmss13/assets/76988376/50b1cbca-ac0f-4856-9e27-8d1004c722f0)
# Changelog :cl: Drathek fix: Fixed erroneous is empty messages when inserting tanks into a flamer pack. soundadd: Added the refill sfx when using the empty canister verb on flamer tanks. /:cl: --------- Co-authored-by: harryob --- code/modules/projectiles/magazines/flamer.dm | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/code/modules/projectiles/magazines/flamer.dm b/code/modules/projectiles/magazines/flamer.dm index 782b6bfe8910..787a0585640a 100644 --- a/code/modules/projectiles/magazines/flamer.dm +++ b/code/modules/projectiles/magazines/flamer.dm @@ -58,6 +58,7 @@ reagents.clear_reagents() + playsound(loc, 'sound/effects/refill.ogg', 25, 1, 3) to_chat(usr, SPAN_NOTICE("You empty out [src]")) update_icon() @@ -71,22 +72,21 @@ G.update_icon() /obj/item/ammo_magazine/flamer_tank/afterattack(obj/target, mob/user , flag) //refuel at fueltanks when we run out of ammo. - if(!istype(target, /obj/structure/reagent_dispensers/fueltank) && !istype(target, /obj/item/tool/weldpack) && !istype(target, /obj/item/storage/backpack/marine/engineerpack)) - return ..() if(get_dist(user,target) > 1) return ..() + if(!istype(target, /obj/structure/reagent_dispensers/fueltank) && !istype(target, /obj/item/tool/weldpack) && !istype(target, /obj/item/storage/backpack/marine/engineerpack)) + return ..() - var/obj/O = target - if(!O.reagents || O.reagents.reagent_list.len < 1) - to_chat(user, SPAN_WARNING("[O] is empty!")) + if(!target.reagents || target.reagents.reagent_list.len < 1) + to_chat(user, SPAN_WARNING("[target] is empty!")) return if(!reagents) create_reagents(max_rounds) - var/datum/reagent/to_add = O.reagents.reagent_list[1] + var/datum/reagent/to_add = target.reagents.reagent_list[1] - if(!istype(to_add) || (length(reagents.reagent_list) && flamer_chem != to_add.id) || length(O.reagents.reagent_list) > 1) + if(!istype(to_add) || (length(reagents.reagent_list) && flamer_chem != to_add.id) || length(target.reagents.reagent_list) > 1) to_chat(user, SPAN_WARNING("You can't mix fuel mixtures!")) return @@ -96,10 +96,11 @@ var/fuel_amt_to_remove = Clamp(to_add.volume, 0, max_rounds - reagents.get_reagent_amount(to_add.id)) if(!fuel_amt_to_remove) - to_chat(user, SPAN_WARNING("[O] is empty!")) + if(!max_rounds) + to_chat(user, SPAN_WARNING("[target] is empty!")) return - O.reagents.remove_reagent(to_add.id, fuel_amt_to_remove) + target.reagents.remove_reagent(to_add.id, fuel_amt_to_remove) reagents.add_reagent(to_add.id, fuel_amt_to_remove) playsound(loc, 'sound/effects/refill.ogg', 25, 1, 3) caliber = to_add.name From 39d2f9888b3142ca3cbf48c969816abf90d25091 Mon Sep 17 00:00:00 2001 From: harryob Date: Fri, 23 Jun 2023 18:27:37 +0100 Subject: [PATCH 27/54] sanitizes some more player input (#3702) closes #3698 --- code/modules/cm_marines/marines_consoles.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/cm_marines/marines_consoles.dm b/code/modules/cm_marines/marines_consoles.dm index 21f8a461a016..3539a43e6c15 100644 --- a/code/modules/cm_marines/marines_consoles.dm +++ b/code/modules/cm_marines/marines_consoles.dm @@ -177,7 +177,7 @@ if(!authenticated || !target_id_card) return - var/new_name = params["name"] // reject_bad_name() can be added here + var/new_name = strip_html(params["name"]) if(!new_name) visible_message(SPAN_NOTICE("[src] buzzes rudely.")) return @@ -191,7 +191,7 @@ return if(target == "Custom") - var/custom_name = params["custom_name"] + var/custom_name = strip_html(params["custom_name"]) if(custom_name) target_id_card.assignment = custom_name else From ab775c7ea8024c2c19a31964fed262da38417801 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 23 Jun 2023 18:29:05 +0100 Subject: [PATCH 28/54] Automatic changelog for PR #3623 [ci skip] --- html/changelogs/AutoChangeLog-pr-3623.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3623.yml diff --git a/html/changelogs/AutoChangeLog-pr-3623.yml b/html/changelogs/AutoChangeLog-pr-3623.yml new file mode 100644 index 000000000000..d0909a0051e9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3623.yml @@ -0,0 +1,5 @@ +author: "Drathek" +delete-after: True +changes: + - bugfix: "Fixed erroneous is empty messages when inserting tanks into a flamer pack." + - soundadd: "Added the refill sfx when using the empty canister verb on flamer tanks." \ No newline at end of file From 9a51e5d4e5db16715e1172415bc8a998bd0fa2df Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Fri, 23 Jun 2023 15:54:45 -0400 Subject: [PATCH 29/54] Devour now turns off lights (#3668) # About the pull request This PR makes it so devour turns off lights. # Explain why it's good for the game This should stop some of the pesky bugs that have been cropping up around lights and devour/regurg. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow fix: Prevented some light bugs with devouring marines /:cl: --------- Co-authored-by: Zonespace <41448081+Zonespace27@users.noreply.github.com> --- code/modules/mob/mob_grab.dm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 81296f346d50..39cc5b25e519 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -141,10 +141,9 @@ X.visible_message(SPAN_WARNING("[X] devours [pulled]!"), \ SPAN_WARNING("You devour [pulled]!"), null, 5) - //IMPORTANT CODER NOTE: Due to us using the old lighting engine, we need to hacky hack hard to get this working properly - //So we're just going to get the lights out of here by forceMoving them to a far-away place - //They will be recovered when regurgitating, since this also calls forceMove - pulled.moveToNullspace() + if(ishuman(pulled)) + var/mob/living/carbon/human/pulled_human = pulled + pulled_human.disable_lights() //Then, we place the mob where it ought to be X.stomach_contents.Add(pulled) From 13be6b625511eee688f0812e98e1cdafb296e801 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 23 Jun 2023 21:03:24 +0100 Subject: [PATCH 30/54] Automatic changelog for PR #3668 [ci skip] --- html/changelogs/AutoChangeLog-pr-3668.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3668.yml diff --git a/html/changelogs/AutoChangeLog-pr-3668.yml b/html/changelogs/AutoChangeLog-pr-3668.yml new file mode 100644 index 000000000000..9d94c2c6f3d0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3668.yml @@ -0,0 +1,4 @@ +author: "Morrow" +delete-after: True +changes: + - bugfix: "Prevented some light bugs with devouring marines" \ No newline at end of file From 39d6b77ce81ad790d3bd196d967202dfd29449f2 Mon Sep 17 00:00:00 2001 From: Steelpoint <6595389+Steelpoint@users.noreply.github.com> Date: Sat, 24 Jun 2023 06:04:31 +0800 Subject: [PATCH 31/54] Adds USCM Poncho To Synth Vendor (#3687) # About the pull request Adds the USCM Poncho as a purchase option to the Synthetic snowflake vendor. # Explain why it's good for the game More ability to customize your shipboard Synthetic is a good thing I believe. # Testing Photographs and Procedure
Screenshots & Videos ![Screenshot 2023-06-21 19 18 53](https://github.com/cmss13-devs/cmss13/assets/6595389/1f07a8b0-197d-43e3-9603-9f3dcd052170)
# Changelog :cl: add: Synthetics may now vend Ponchos. /:cl: Co-authored-by: Steelpoint --- code/game/machinery/vending/vendor_types/crew/synthetic.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/machinery/vending/vendor_types/crew/synthetic.dm b/code/game/machinery/vending/vendor_types/crew/synthetic.dm index bd403c65c31b..1d8e5e289066 100644 --- a/code/game/machinery/vending/vendor_types/crew/synthetic.dm +++ b/code/game/machinery/vending/vendor_types/crew/synthetic.dm @@ -244,6 +244,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_synth_snowflake, list( list("Labcoat", 12, /obj/item/clothing/suit/storage/labcoat, null, VENDOR_ITEM_REGULAR), list("Labcoat, Researcher", 12, /obj/item/clothing/suit/storage/labcoat/researcher, null, VENDOR_ITEM_REGULAR), list("RO Jacket", 12, /obj/item/clothing/suit/storage/RO, null, VENDOR_ITEM_REGULAR), + list("USCM Poncho", 12, /obj/item/clothing/accessory/poncho, null, VENDOR_ITEM_REGULAR), list("BACKPACK", 0, null, null, null), list("Backpack, Industrial", 12, /obj/item/storage/backpack/industrial, null, VENDOR_ITEM_REGULAR), From 316057c45b7fa870c997044a3bd58a03f0cc68ed Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 23 Jun 2023 23:13:25 +0100 Subject: [PATCH 32/54] Automatic changelog for PR #3687 [ci skip] --- html/changelogs/AutoChangeLog-pr-3687.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3687.yml diff --git a/html/changelogs/AutoChangeLog-pr-3687.yml b/html/changelogs/AutoChangeLog-pr-3687.yml new file mode 100644 index 000000000000..f2a9cc2507d3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3687.yml @@ -0,0 +1,4 @@ +author: "Steelpoint" +delete-after: True +changes: + - rscadd: "Synthetics may now vend Ponchos." \ No newline at end of file From 76533dec9795b7641cd1681eed91d1c477533d36 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Sat, 24 Jun 2023 01:44:35 +0000 Subject: [PATCH 33/54] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-3623.yml | 5 ----- html/changelogs/AutoChangeLog-pr-3636.yml | 6 ------ html/changelogs/AutoChangeLog-pr-3652.yml | 5 ----- html/changelogs/AutoChangeLog-pr-3668.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3687.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3692.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3696.yml | 4 ---- html/changelogs/archive/2023-06.yml | 22 ++++++++++++++++++++++ 8 files changed, 22 insertions(+), 32 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-3623.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3636.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3652.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3668.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3687.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3692.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3696.yml diff --git a/html/changelogs/AutoChangeLog-pr-3623.yml b/html/changelogs/AutoChangeLog-pr-3623.yml deleted file mode 100644 index d0909a0051e9..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3623.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - bugfix: "Fixed erroneous is empty messages when inserting tanks into a flamer pack." - - soundadd: "Added the refill sfx when using the empty canister verb on flamer tanks." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3636.yml b/html/changelogs/AutoChangeLog-pr-3636.yml deleted file mode 100644 index a1dcf5fbeb71..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3636.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - rscadd: "The selection to become a xeno larva is now based on timeofdeath rather than random and also sends a message to all candidates when the queue moves. Playing as a facehugger or on admin z-levels (thunderdome) will not affect your relative place in queue. The join xeno action will also display the last queue message for you when you allow xeno candidacy." - - bugfix: "Fixed gibbed humans not properly setting their timeofdeath when on an admin z-level." - - bugfix: "Fixed a bad del on shuttle doors when a shuttle deletes (such as intoTheSunset)." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3652.yml b/html/changelogs/AutoChangeLog-pr-3652.yml deleted file mode 100644 index d95df39d8567..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3652.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "realforest2001" -delete-after: True -changes: - - admin: "Improves logging for admin deadchat." - - admin: "Adds logging for xeno evolution." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3668.yml b/html/changelogs/AutoChangeLog-pr-3668.yml deleted file mode 100644 index 9d94c2c6f3d0..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3668.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Morrow" -delete-after: True -changes: - - bugfix: "Prevented some light bugs with devouring marines" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3687.yml b/html/changelogs/AutoChangeLog-pr-3687.yml deleted file mode 100644 index f2a9cc2507d3..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3687.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Steelpoint" -delete-after: True -changes: - - rscadd: "Synthetics may now vend Ponchos." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3692.yml b/html/changelogs/AutoChangeLog-pr-3692.yml deleted file mode 100644 index cf20a4947af4..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3692.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "theselfish" -delete-after: True -changes: - - qol: "Added the Corpsman Helmet to Req's surplus vendor." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3696.yml b/html/changelogs/AutoChangeLog-pr-3696.yml deleted file mode 100644 index dabfba255741..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3696.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Morrow" -delete-after: True -changes: - - bugfix: "Fixed two gun light attachment issues" \ No newline at end of file diff --git a/html/changelogs/archive/2023-06.yml b/html/changelogs/archive/2023-06.yml index 9e9081238a2a..f1ae2b2dd14e 100644 --- a/html/changelogs/archive/2023-06.yml +++ b/html/changelogs/archive/2023-06.yml @@ -318,3 +318,25 @@ 2023-06-23: harryob: - server: server's can now support using a cdn for web assets +2023-06-24: + Drathek: + - rscadd: The selection to become a xeno larva is now based on timeofdeath rather + than random and also sends a message to all candidates when the queue moves. + Playing as a facehugger or on admin z-levels (thunderdome) will not affect your + relative place in queue. The join xeno action will also display the last queue + message for you when you allow xeno candidacy. + - bugfix: Fixed gibbed humans not properly setting their timeofdeath when on an + admin z-level. + - bugfix: Fixed a bad del on shuttle doors when a shuttle deletes (such as intoTheSunset). + - bugfix: Fixed erroneous is empty messages when inserting tanks into a flamer pack. + - soundadd: Added the refill sfx when using the empty canister verb on flamer tanks. + Morrow: + - bugfix: Prevented some light bugs with devouring marines + - bugfix: Fixed two gun light attachment issues + Steelpoint: + - rscadd: Synthetics may now vend Ponchos. + realforest2001: + - admin: Improves logging for admin deadchat. + - admin: Adds logging for xeno evolution. + theselfish: + - qol: Added the Corpsman Helmet to Req's surplus vendor. From 71455d4fd8947610a25d47729429a35ed8a2a1c2 Mon Sep 17 00:00:00 2001 From: Segrain Date: Sat, 24 Jun 2023 11:33:43 +0400 Subject: [PATCH 34/54] Fix for dummy rotation in character setup. (#3699) # About the pull request Followup to #3516. That PR changed the general click behaviour from `if (click(A, mods) | A.clicked(src, mods, location, params))` to use `||` instead. And in Byond, that means quick resolution: if left side is true, then right side is not evaluated - thus not executed - at all. ~~I am not sure what exactly was that meant to address (or whether it was intentional at all, for that matter),~~ but as it happens, `/mob/new_player/click()` is set to always simply return true while all the code for those arrows is in their `clicked()`. Solution is obvious then. P.S. On second thought, reading the PR does explain the PR. But quick resolution is not exactly intuitive, and even though it is probably highly unlikely to ever change, there is probably no need to rely on it so implicitly. While I have the file open anyway, might as well make returning after the left half alone explicit. # Explain why it's good for the game Is fix. # Changelog :cl: fix: Preview dummy in character setup once again can be rotated. /:cl: --- code/_onclick/click.dm | 4 +++- code/_onclick/other_mobs.dm | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index ad2f305790d2..affbc28cdd45 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -71,7 +71,9 @@ return // Click handled elsewhere. (These clicks are not affected by the next_move cooldown) - if (click(A, mods) || A.clicked(src, mods, location, params)) + if(click(A, mods)) + return + if(A.clicked(src, mods, location, params)) return // Default click functions from here on. diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index a8ed20f5c4b3..9c9784286d09 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -34,4 +34,4 @@ Have no reason to click on anything at all. */ /mob/new_player/click() - return 1 + return From 04b47c92e7827614f76debf6485bc679c8379d2a Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 24 Jun 2023 08:42:04 +0100 Subject: [PATCH 35/54] Automatic changelog for PR #3699 [ci skip] --- html/changelogs/AutoChangeLog-pr-3699.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3699.yml diff --git a/html/changelogs/AutoChangeLog-pr-3699.yml b/html/changelogs/AutoChangeLog-pr-3699.yml new file mode 100644 index 000000000000..5cac5307b4c6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3699.yml @@ -0,0 +1,4 @@ +author: "Segrain" +delete-after: True +changes: + - bugfix: "Preview dummy in character setup once again can be rotated." \ No newline at end of file From 610c8b3099f479c9948ff7e9df2151c2370c1f2f Mon Sep 17 00:00:00 2001 From: Segrain Date: Sat, 24 Jun 2023 11:33:54 +0400 Subject: [PATCH 36/54] Hive core and dead larvas. (#3700) # About the pull request Hive core, by design, absorbs AFK larvas to let somebody else actually play instead. And as long as it has been a thing, the definition of "AFK" was actually "without a client", so a dead larva that ghosted was absorbed all the same and replaced with a new alive larva - while dead larvas that did not ghost were seen as being actively played and left alone. Frankly, if a larva dies without the core and entire hive being destroyed, it was most likely running out somewhere whither it has no business going. We refund these anyway. Might as well formally declare it an intended mechanic that dead larvas can be recycled at core. Also, funny as it might be, it should only work on the hive's _own_ larvas. # Explain why it's good for the game Closes #3667. # Changelog :cl: fix: Hive core now always correctly absorbs hive's dead larvas. /:cl: --- code/modules/cm_aliens/structures/special/pylon_core.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/cm_aliens/structures/special/pylon_core.dm b/code/modules/cm_aliens/structures/special/pylon_core.dm index 08aa2f86c1bc..40b4ad8e1718 100644 --- a/code/modules/cm_aliens/structures/special/pylon_core.dm +++ b/code/modules/cm_aliens/structures/special/pylon_core.dm @@ -137,7 +137,7 @@ // Handle spawning larva if core is connected to a hive if(linked_hive) for(var/mob/living/carbon/xenomorph/larva/L in range(2, src)) - if(!L.ckey && L.burrowable && !QDELETED(L)) + if((!L.ckey || L.stat == DEAD) && L.burrowable && (L.hivenumber == linked_hive.hivenumber) && !QDELETED(L)) visible_message(SPAN_XENODANGER("[L] quickly burrows into \the [src].")) linked_hive.stored_larva++ linked_hive.hive_ui.update_burrowed_larva() From 036b4cd019ebec1bf3d41513620e5bd105b37353 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 24 Jun 2023 08:56:37 +0100 Subject: [PATCH 37/54] Automatic changelog for PR #3700 [ci skip] --- html/changelogs/AutoChangeLog-pr-3700.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3700.yml diff --git a/html/changelogs/AutoChangeLog-pr-3700.yml b/html/changelogs/AutoChangeLog-pr-3700.yml new file mode 100644 index 000000000000..5aa90e4d8ece --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3700.yml @@ -0,0 +1,4 @@ +author: "Segrain" +delete-after: True +changes: + - bugfix: "Hive core now always correctly absorbs hive's dead larvas." \ No newline at end of file From db5a3892631223bb7fcab81146356b049edce082 Mon Sep 17 00:00:00 2001 From: Sargeantmuffinman <104228030+Sargeantmuffinman@users.noreply.github.com> Date: Sat, 24 Jun 2023 08:34:11 +0100 Subject: [PATCH 38/54] Email rewrites (#3701) # About the pull request Rewrites and or updates some of the emails I created while adding two new ones. These are simple text changes. # Explain why it's good for the game More consistent writing and lore is great for the game. # Testing Photographs and Procedure
Screenshots & Videos ![image](https://github.com/cmss13-devs/cmss13/assets/104228030/8264a067-b147-4093-abde-7fa08b68100c) ![image](https://github.com/cmss13-devs/cmss13/assets/104228030/efd81d99-2d73-4bc9-a1c9-28ca945c6823) ![image](https://github.com/cmss13-devs/cmss13/assets/104228030/88155524-7fea-4809-b036-b52fc56a0eb9) ![image](https://github.com/cmss13-devs/cmss13/assets/104228030/9db716d6-7734-440a-9237-56e8879c2e01) ![image](https://github.com/cmss13-devs/cmss13/assets/104228030/fca43d28-71a9-4a8c-919b-610561a32892)
# Changelog :cl: add: Added two new emails to the Almayer's personal computers and rewrote 3 other emails. /:cl: --- code/datums/fluff_emails.dm | 128 ++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/code/datums/fluff_emails.dm b/code/datums/fluff_emails.dm index 6dd8cd590860..f7083541dd5a 100644 --- a/code/datums/fluff_emails.dm +++ b/code/datums/fluff_emails.dm @@ -93,9 +93,9 @@ /datum/fluff_email/almayer/themajor title = "The Major?" entry_text = {" - I keep forgetting what the new Major's name is. I got quizzed by one of the jackass staff officers last week about the captain's name, - and I absolutely spilled my marbles. PCF Mable was watching too, and she probably thinks I've got rocks in my head. I know it's been weeks - since the new captain took over, but for some reason the name keeps escaping me when it matters. Either the cryo-sleepers are juicing my + I keep forgetting what the new Major's name is. I got quizzed by one of the jackass staff officers last week about the Major's name, + and I absolutely spilled my marbles. PFC Mable was watching too, and she probably thinks I've got rocks in my head. I know it's been weeks + since the new Major took over, but for some reason the name keeps escaping me when it matters. Either the cryo-sleepers are juicing my memory capacity or the CO keeps changing their name and not telling anybody. Maybe next jump I'll scrawl it on a sticky note and plaster it to the inside of my sleeper pod. I can't be the only one having this problem. @@ -105,7 +105,8 @@ /datum/fluff_email/almayer/tunes title = "RE: Tunes" entry_text = {" - Cryosleep is killing me, man. Inside and outside. I mean really, they expect us to sit in that tube for god only knows how long, and when we wake up? It's all 'grab a crappy protein bar and grab your gear, you're going to war, Marine!' Bullshit. + Cryosleep is killing me, man. Inside and outside. I mean really, they expect us to sit in that tube for god only knows how long, and when we wake up? + It's all 'grab a crappy protein bar and grab your gear, you're going to war, Marine!' Bullshit.

Anywho, I've been thinking how to make the whole thing more bearable. Tried to take a plush from the bunks with me inside. That dickwad MP took it away from me though, said it was against Operating Procedure. Like I care. Can't do anything fun around here, right? @@ -113,82 +114,81 @@ I don't usually use these things, and frankly that vendor near Medbay has waaay too many cassettes to choose from. Not that I know most songs on them anywho.

- I saw you with a Walkman from time to time, so... any chances you could recommend a tape to me? Or two, I'm not gonna be picky. Just anything to start out with, I just want some nice sounds. Please, I'm gonna go mad if I don't do something about my cryophobia or whatever. This might just help with that. + I saw you with a Walkman from time to time, so... any chances you could recommend a tape to me? Or two, I'm not gonna be picky. + Just anything to start out with, I just want some nice sounds. Please, I'm gonna go mad if I don't do something about my cryophobia or whatever. + This might just help with that. "} -/datum/fluff_email/almayer/lasergun - title = "RE: Lasergun" +/datum/fluff_email/almayer/lasergun1 + title = "Prototype Weapon" entry_text = {" - Hey REDACTED. Thanks for letting me test out the laser gun. That thing is a factual blast to use. It literally set the targets down range on fire! Those cooling coils work wonders. Used it a good few times and the barrel didn't explode! + This thing is an absolute blast to use. + It disintegrated some of the targets down range but you're going to need to work on those cooling coils. + I used it a few times and I'm seeing the front barrel glow red.

- Hell, it's even pretty accurate too. I know there's like, a couple of prototypes issued to some USCM detachments but we got to have this shit in production one day. It's just good. Now, I don't think it's gonna replace the old Mark two's but it would be a nice addition for some of our grunts that prefer the high tech approach. You know the ones, all nerdy and gadget loving geeks in the corps. Hell I can already hear them glossing over this thing in their sleep. + Surprisingly accurate too despite being a prototype. + I know there's like, a couple of prototypes issued to some USCM detachments, but we got to have this shit in production one day.

- Anyway, I've already attached the weapon report you wanted on this thing back to the email. Hopefully you guys in R&D will get some useful info out of it. + Even as a prototype, it's leagues better than some of the junk we're issued. + Now, I don't think it's going to replace the old Mark Twos, but it would be a nice addition for some of our grunts that prefer the high-tech approach.
- Alright see you when I see you - REDACTED
-
- RE:RE: The Plasma Gun (It's called the XM99 Phased Plasma Pulse Rifle) - Hey REDACTED, REDACTED here. Thanks for the report but I'm going to need you to send the Phased Plasma Pulse Rifle back to me. Apparently we're not allowed to ship them out for testing... I guess I must've missed that memo. The memo came three days after I shipped it out to you. Sorry for the inconvenience. You know where to send it back to and how to. I did tell you how right? There was a small pamphlet in the casing if you forgot. -
-
- Don't think this is going to be issued en masse for a while, it's still going under trials and when I got the weapon report you sent me, they sent in a new updated design for the gun which invalidated most of the things in the report, shame. Looks more promising than the last one though. -
-
- Okay, I'll hopefully be seeing the XM99 Phased Plasma Pulse Rifle in the lab soon. -
-
- REDACTED RE:RE:RE: The Plasma Gun (It's called the XM99 Phased Plasma Pulse Rifle) -
- Holy shit, what the fuck did you do to the damned thing? When I opened the case, I could see fractures and scratches everywhere! Did you give this to the entire platoon to try out? And from the data I'm reading, you fired over 178 shots with this. I only gave you two batteries for the thing. -
-
- How the hell did you recharge it?! The prototype can't take any other forms of power other than those two batteries. And even then, you can't recharge those specially made batteries either without the equipment back in the lab here. And the inside of the barrel is all messed up man. The cooling coils expired and there're bits of the barrel loose inside of it. How the hell did you not notice bits of the inside of the barrel spewing out from the muzzle man?! -
-
- Right. They've threatened to drop me from the project if something like this happens again. In the rare case that I send another prototype out, it had better come back in one piece. And I mean in pristine condition, you got that? -
-
Regards, -
REDACTED + You know the ones, all nerdy and gadget loving geeks in the corps. Hell, I can already hear them glossing over this thing in their sleep. + My report has been sent back to you and I'm really excited to see how this turns out. + + "} + + +/datum/fluff_email/almayer/lasergun2 + title = "New Prototype Design" + entry_text = {" + Thanks for sending the report in, we've been mulling over the data you sent over. + We've updated the design for the prototype which solves most of the problems everyone has encountered. + This one looks more promising than the last one. + And as much as everyone wants this done and shippped, I don't think this is going to be issued en masse for a good while. "} /datum/fluff_email/almayer/beatup - title = "RE: Beat Up" + title = "Beat Up" entry_text = {" - Yo. -
-
- Man, last mission was an absolute shit show. The USS Heyst got their shit kicked in with a missile and we got our cargo hold set on fire by that damn suicide craft. They even blew up most of our good ammo too! Now we're left with the soft point backup munitions. Shit, most of 1st platoon is pretty much out of action. Lotta folks are in sickbay and the rest of us are heading off to cryosleep, well what's left of us. -
-
- When the comms got cut and we were cut off from command; Squad Foxtrot was immediately ambushed on the logistics route to get supplies in and out of the combat zone. I suspect they were taping into your comms to find the literal perfect moment to fuck with our logistics. Thankfully those trucks of ours had their engines tricked out by the techies back on LV-176 in the civilian garage. Those guys hosted rally races around their colony and Sergeant DATA EXPUNGED won a few races for us. Instead of taking their trophy, he pulled a few favors to get our trucks pimped out with better engines. We owe our lives to Sarge for winning one for the corps. -
-
- Hell, at least we're all going back to Chinook Station to get resupplied. Hopefully the wounded wake up to the docs on station rather than our poor and cramped excuse for a medical bay. The number of times the medbay has been packed with wounded where even the damn front lobby had bodies lining up on the sides of the walls waiting for treatment; it still amazes. Worse still was the stench from all the blood and guts, it made it hell for the maint. techs to clean up afterwards. -
- I'm still surprised those doctors we had on hand took care of most of them so quickly, even if most of them are still injured heading to the fridge. -
-
- I read the After-Action Report which the Heyst's XO did, and they're leaving out a few details. When it came to that city, they left out how we had to DATA EXPUNGED. The entire building collapsed with them in it too. Damn shame we couldn't save them. -
-
- The only damn silver lining i see in this shit is that the AI is going to cycle cryo again and we ain't waking to deal with whatever bullshit is happening next time. 2nd Platoon is dealing with that, cause 1st platoon is undermanned as is with our casualties. I heard they have a few screws loose, not that ours are entirely in either! But I don't care, it's their problem now y'know? -
-
- Worst case scenario, we don't wake up at all. -
- Right, see you back on station friend. -
-
- Regards, -
- REDACTED + Man last mission was an absolute shit show. +
+ The USS Heyst got their shit kicked in with a missile and we got our cargo hold set on fire. And most of our good ammo is gone too! + Now we're left with the FMJs and the older AP munitions. What's worse is that most of 1st platoon is pretty much out of action. + Lotta folks are in the sickbay and the rest of us are heading off to cryosleep, well what's left of us. There's not many of the old guard left I'm afraid. + Until we get reinforced with more bodies, command has given the go ahead to merge 2nd platoon into 1st for the time being. + + "} + + +/datum/fluff_email/almayer/rallyrace + title = "Rally Racing" + entry_text = {" + Hey, remember last shore leave on LV-179? Man, that was one crazy night. The folks at the colony had setup a rally race with their tractors all stripped of non-essentials. + LCPL Millard got pretty friendly with the locals and got himself into the competition. + We all put in a little wager to see if he'd even get close to first place or even survive to the finish line. + Now most of the boys bet a fair amount against him since he was pretty new to our outfit, yet I've been out on detail with the guy. +
+
+ Millard grew up on one of those shake and bake colonies and used to drive the big daisies around. + He knew the ins and outs of what made them tick. The few of us who had faith in him reaped everyone else's + paycheck for the week with Millard finishing first place by a near country mile. "} + +/datum/fluff_email/almayer/missing + title = "Missing Personnel" + entry_text = {" + Has anyone seen Mendoza around? He owes me half of his paycheck from last month's poker game. + Everyone's payday was a week ago and we're all set to head back to Chinook station. + Could have sworn I saw him near the cargo elevator yesterday. + I'll catch him back at base once we've docked because I need that money to pay off my tab at the bar. + + "} + From 807387b2930f74c389bef793bd44b3a77c53c710 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 24 Jun 2023 09:11:38 +0100 Subject: [PATCH 39/54] Automatic changelog for PR #3701 [ci skip] --- html/changelogs/AutoChangeLog-pr-3701.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3701.yml diff --git a/html/changelogs/AutoChangeLog-pr-3701.yml b/html/changelogs/AutoChangeLog-pr-3701.yml new file mode 100644 index 000000000000..41559592d55d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3701.yml @@ -0,0 +1,4 @@ +author: "Sargeantmuffinman" +delete-after: True +changes: + - rscadd: "Added two new emails to the Almayer's personal computers and rewrote 3 other emails." \ No newline at end of file From da8b72896ebad2b02d0f79249e17dbfea761895c Mon Sep 17 00:00:00 2001 From: Changelogs Date: Sun, 25 Jun 2023 01:57:10 +0000 Subject: [PATCH 40/54] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-3699.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3700.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3701.yml | 4 ---- html/changelogs/archive/2023-06.yml | 7 +++++++ 4 files changed, 7 insertions(+), 12 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-3699.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3700.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3701.yml diff --git a/html/changelogs/AutoChangeLog-pr-3699.yml b/html/changelogs/AutoChangeLog-pr-3699.yml deleted file mode 100644 index 5cac5307b4c6..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3699.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Segrain" -delete-after: True -changes: - - bugfix: "Preview dummy in character setup once again can be rotated." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3700.yml b/html/changelogs/AutoChangeLog-pr-3700.yml deleted file mode 100644 index 5aa90e4d8ece..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3700.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Segrain" -delete-after: True -changes: - - bugfix: "Hive core now always correctly absorbs hive's dead larvas." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3701.yml b/html/changelogs/AutoChangeLog-pr-3701.yml deleted file mode 100644 index 41559592d55d..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3701.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Sargeantmuffinman" -delete-after: True -changes: - - rscadd: "Added two new emails to the Almayer's personal computers and rewrote 3 other emails." \ No newline at end of file diff --git a/html/changelogs/archive/2023-06.yml b/html/changelogs/archive/2023-06.yml index f1ae2b2dd14e..fafefe4203db 100644 --- a/html/changelogs/archive/2023-06.yml +++ b/html/changelogs/archive/2023-06.yml @@ -340,3 +340,10 @@ - admin: Adds logging for xeno evolution. theselfish: - qol: Added the Corpsman Helmet to Req's surplus vendor. +2023-06-25: + Sargeantmuffinman: + - rscadd: Added two new emails to the Almayer's personal computers and rewrote 3 + other emails. + Segrain: + - bugfix: Hive core now always correctly absorbs hive's dead larvas. + - bugfix: Preview dummy in character setup once again can be rotated. From 5ef4998bb35da31d73e53d8be7790c74d164a4b9 Mon Sep 17 00:00:00 2001 From: Drathek <76988376+Drulikar@users.noreply.github.com> Date: Sat, 24 Jun 2023 22:06:42 -0700 Subject: [PATCH 41/54] Fix yank object verb for others (#3705) # About the pull request This PR fixes an oversight where the yank object verb when used to yank an object out of someone other than yourself would test if the person with the object had a free hand, rather than the person trying to do the action. # Explain why it's good for the game Rather than getting (such as when a object gets stuck in a zombie who has claws in each hand): ![image](https://github.com/cmss13-devs/cmss13/assets/76988376/47a8891d-18ea-4cf0-a0fc-73a0c295318a) You can yank it out: ![stab](https://github.com/cmss13-devs/cmss13/assets/76988376/8fe6cce6-cbcc-4239-bd4e-b642d0f6b7c4) # Testing Photographs and Procedure
Screenshots & Videos See Explanation.
# Changelog :cl: Drathek fix: Fixed the yank object verb not testing who is actually performing the action has a free hand /:cl: --- code/modules/mob/mob.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 7803c15da523..0c182fb0fe9c 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -843,7 +843,7 @@ note dizziness decrements automatically in the mob's Life() proc. return FALSE to_chat(src, SPAN_WARNING("You attempt to get a good grip on [selection] in your body.")) else - if(get_active_hand()) + if(usr.get_active_hand()) to_chat(usr, SPAN_WARNING("You need an empty hand for this!")) return FALSE to_chat(usr, SPAN_WARNING("You attempt to get a good grip on [selection] in [src]'s body.")) From da3c30303cb0cc4b477065e9dfa6323db76ce9f0 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sun, 25 Jun 2023 06:15:05 +0100 Subject: [PATCH 42/54] Automatic changelog for PR #3705 [ci skip] --- html/changelogs/AutoChangeLog-pr-3705.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3705.yml diff --git a/html/changelogs/AutoChangeLog-pr-3705.yml b/html/changelogs/AutoChangeLog-pr-3705.yml new file mode 100644 index 000000000000..5389f0af6869 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3705.yml @@ -0,0 +1,4 @@ +author: "Drathek" +delete-after: True +changes: + - bugfix: "Fixed the yank object verb not testing who is actually performing the action has a free hand" \ No newline at end of file From cec2b4bfbcebf1de5c8e1deefbb4d33db0912e05 Mon Sep 17 00:00:00 2001 From: blackdragonTOW <31581761+blackdragonTOW@users.noreply.github.com> Date: Sat, 24 Jun 2023 22:07:03 -0700 Subject: [PATCH 43/54] String Changes for Tips (#3707) # About the pull request Updates Memetips, Xenotips, and Marinetips to have better grammar and removes typos. # Explain why it's good for the game Everyone gets very tired when seeing typos in the round start tips. # Testing Photographs and Procedure
Screenshots & Videos
# Changelog Altered the Meme/Xeno/Marine tips that display at round start. :cl: spellcheck: multiple typos and grammar changes in the round start tooltips. /:cl: --- strings/marinetips.txt | 18 +++++++++--------- strings/metatips.txt | 8 ++++---- strings/xenotips.txt | 26 +++++++++++++------------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/strings/marinetips.txt b/strings/marinetips.txt index 620dc8710400..cf808884f1e5 100644 --- a/strings/marinetips.txt +++ b/strings/marinetips.txt @@ -28,7 +28,7 @@ Examine your gun and click [See combat statistics] to view information such as d Xenomorphs who resist while on fire are stunned for some time and emit light. Use that time to catch up and finish them off! When you have shrapnel embedded, take out your boot knife and use it in your hand to rip them out of your body. If your weapon has a bayonet, you can manually pry open unpowered doors by clicking on them with the gun. Click on the door again to close it. UPP bayonets can pry them open quicker. -Items on the floor can be shot. Shoot a misthrown HEDP away to save your buddies! +Items on the floor can be shot. Shoot a poorly thrown HEDP away to save your buddies! You can hold a bayonet or throwing knife on your mask slot. Always be prepared. Xenomorphs can't apply huggers to marines if they're on fire. Dragging a Nanomed onto yourself instantly gives a Health Analyzer report. Always know what's wrong with you. @@ -46,18 +46,18 @@ By right clicking your medical belt and selecting "toggle belt mode", you can ta You can put screwdrivers, cigarettes, and some other things in your second ear slot! Pilots : there is one of each engine upgrade in the hangar at the start of the round, saving you the point cost of having to print out a pair of each. You can use a hand labeler (as found in squad prep rooms) to name your equipment and make it less likely to be stolen. -You can use a health analyser in hand (Z key) to check the last scan readout from it. +You can use a health analyzer in hand (Z key) to check the last scan readout from it. Holocards are a useful triage tool for doctors and medics. Ensure you assign them (examine the marine with shift-click and select an appropriate holocard) to marines who have taken damage that cannot be healed without surgery. (Hint : major organ damage or larval infection = red card!) Escape pods are designed for only three occupants - more than that, or if a larger xenomorph is in the pod, and it will malfunction and blow up on launch. A misloaded OB can deviate severely from the intended target area - ensure you load them correctly! -The XO and CO are trained in powerloader use and engineering, and can load the OB. +The XO and CO are trained in Power Loader use and engineering, and can load the OB. You can change what your SL tracker beacon is tracking by right clicking on your headset and clicking "Switch Tracker Target". Boilers emit light - not every glow from around the corner is friendly! You can carry a variety of items inside your helmet - from gauze and cigarettes to flares and screwdrivers. CIC staff can track every USCM-aligned person via the suit sensors console and overwatch console - useful for finding escaped prisoners or dead marines. When the M7 RPG is fired, it creates a substantial shockwave behind it that can stun and harm marines standing too close. Watch your backblast! Remember that you need to put a defibrillator's paddles away in order to store it. -W-Y PMCs do not have marine IFF. Don't fire smartguns through them! +W-Y PMCs do not have marine IFF. Don't fire Smartguns through them! To talk on multiple radio channels at once, put a COMMA [,] before your message and add up to four prefixes. E.g, ,abcd talks on all squad channels at once. Put .w or :w before your message to whisper. Another way to whisper is to use the verb "whisper" in the IC tab or command bar. For Vehicle Crewmen : it is often safer to repair the parts of your APC or tank inside the vehicle than outside it. @@ -75,13 +75,13 @@ Intel Officers can be put in a squad by going to CIC and requesting it. Any marine can perform CPR. On dead marines, this will increase the time they have until they become unrevivable. If you've been pounced on and your squad is unloading into the target, you can hit the 'rest' button to stay down so you don't get filled with lead after getting up. You can check the landing zone as a marine in the status panel. -Functioning night vision goggles can be recharged with batteries. Broken night vision goggles can be repaired by an Engineer with a screwdriver. Not the loadout ones though, those are unfixable and unchargeable. -You can put a pistol belt on your suit slot. (Just grab a rifle instead..) +Functioning night vision goggles can be recharged with batteries. Broken night vision goggles can be repaired by an Engineer with a screwdriver. Not the loadout ones though, those cannot be fixed. +You can put a pistol belt on your suit slot. (Just grab a rifle instead.) Alt-clicking the Squad Leader tracker lets you track your fireteam leader instead. -Armor has a randomized reduction in effectiveness, and does not protect the digits. Take the wiki damage values as a best case scenario. +Armor has a randomized reduction in effectiveness, and does not protect the digits. Take the wiki damage values as a best-case scenario. You can click on your Security Access Tuner (multitool) in your hand to locate the area's APC if there is one. Clicking on your sprite with help intent will let you check your body, seeing where your fractures and other wounds are. Armor has insulative properties - taking it off will help you cool off and take less damage faster if you've been set on fire. -Both foldable cades & plasteel cades if loosened and folded down can be transported in crates! In this way, you can use the crate as a portable breach-repair kit, or dragged (or carried via Powerloader) to an unsecure area for quick defensive set up. +Both foldable cades & plasteel cades if loosened and folded down can be transported in crates! In this way, you can use the crate as a portable breach-repair kit, or dragged (or carried via Power Loader) to an unsecure area for quick defensive set up. The fuel tank pouch doesn't just carry fuel for an incinerator- they can also carry full-size extinguishers. Toolbelts & tool pouches also may hold miniature extinguishers. -The M2C heavy machinegunner belt rig can also carry C4, breaching charges, and most tools. +The M2C heavy machine gunner belt rig can also carry C4, breaching charges, and most tools. diff --git a/strings/metatips.txt b/strings/metatips.txt index 4b69af764aeb..f694da02b5bf 100644 --- a/strings/metatips.txt +++ b/strings/metatips.txt @@ -1,13 +1,13 @@ -Remember hotkeys and marcos can be customized to your liking. Hotkeys can be accessed in your preferences, and macros can be edited in the Byond macro editor, available in the top left drop down menu (click the Byond logo in the corner of the game window). -If you're unsure about a gameplay mechanic, use the 'mentorhelp' verb in the Admins tab to ask veteran players on the subject. +Remember hotkeys and macros can be customized to your liking. Hotkeys can be accessed in your preferences, and macros can be edited in the Byond macro editor, available in the top left drop down menu (click the Byond logo in the corner of the game window). +If you're unsure about a gameplay mechanic, use the 'mentorhelp' verb in the Admin tab to ask veteran players on the subject. Try not to get too mad about dying. We’re all here to have fun. After dying, ask yourself what you did wrong and make a mental note to not make the same mistake again. Communication, be it from a marine to a marine, a drone to the queen, or command to everyone, is vital and information on flanks can change how the entire round plays out. As an alien or marine, be careful of the flank, regardless of if the push is going well or stalling out. Half of getting good is knowing to be aggressive. The other half is knowing when not to be aggressive. -Alt-click a storage item to draw the last item in it (last non-weapon if it's a weapon belt). Middle-click a storage item to inmediately open it, and middle-click structures to attempt to vault them. +Alt-click a storage item to draw the last item in it (last non-weapon if it's a weapon belt). Middle-click a storage item to immediately open it, and middle-click structures to attempt to vault them. Use "North, South, West, East" when referring to locations in-game rather than "up, down, left, right". You shouldn't ignore what your allies are up to. Sometimes they can be organizing a flank in hivemind/radio, sometimes they can be walking up behind you with a slug-loaded shotgun. Either way, it pays to be alert to what they're doing, as much to as what the enemies are. -The Wiki (https://cm-ss13.com/wiki) is a very useful repository of information about the game, such as weapons, equipment, xenomorph castes and their strains. It may not be fully up to date the majority of the time, but the basics are usually accurate. +The Wiki (https://cm-ss13.com/wiki) is a very useful repository of information about the game, such as weapons, equipment, xenomorph castes and their strains. It may not be fully up to date much of the time, but the basics are usually accurate. As an observer, you may see how much remaining hijack time is left in the status panel. Embrace the suck. diff --git a/strings/xenotips.txt b/strings/xenotips.txt index 4e98be577a61..2ca2964ae2d5 100644 --- a/strings/xenotips.txt +++ b/strings/xenotips.txt @@ -1,6 +1,6 @@ Acid pillars can be sneakily placed next to a door in order to surprise marines. -Alien structures like clusters, walls, or pillars are absolutely vital to your victory, be it as cover or to delay and funnel marines. -Always thank your drones and hivelords for supporting the hive! +Alien structures like clusters, walls, or pillars are vital to your victory, be it as cover or to delay and funnel marines. +Always thank your drones and Hivelords for supporting the hive! Don't underestimate survivors. They have no armor but that makes them very fast, they're inherently hardier than marines and have various tricks up their sleeves. While the Queen is de-ovied, the hive does not gain evolution points. Try out new castes or strains that you might have passed up initially. You might find them to be surprisingly fun. @@ -16,21 +16,21 @@ If a fellow alien is stunned, be sure to drag them to safety. On help intent, click a xenomorph who is on fire to pat them out. This works on marines too! Frenzy increases your speed and damage, Recovery increases your health regeneration, and Warding increases the time you have until you bleed out in critical health. Remember that, as a Xenomorph, you can fully disable your night-vision. This helps put into perspective how hidden your position is to marines onscreen. -You can devour bursted corpses in order to transport them to the Spawn Pool or Egg Morpher easier. +You can devour burst corpses in order to transport them to the Spawn Pool or Egg Morpher easier. The bigger you are, the more time it'll take to enter a tunnel. -Drag yourself onto a hole in a wall as a medium-sized or smaller xeno to pass through it. +Drag yourself onto a hole in a wall as a medium-sized or smaller Xeno to pass through it. Claymores have directional explosions. Set them off early by slashing them from behind. If you have difficulty clicking marines, try using Directional Slashing, though there's no directional slashing for abilities. You can diagonally pounce through the corners of fire as a Lurker or Runner without getting ignited. -When playing as xeno, consider aiming at the limbs instead of the chest. Marine armour doesn't protect the arms and legs as well as it does the body. -As xeno, you can break Night-Vision goggles that some marines wear on their helmets. Just aim for the head and slash until the goggles shatter. +When playing as Xeno, consider aiming at the limbs instead of the chest. Marine armor doesn't protect the arms and legs as well as it does the body. +As Xeno, you can break Night-Vision goggles that some marines wear on their helmets. Just aim for the head and slash until the goggles shatter. Pounces are ineffective on marines who are laying down. -You may rest inmediately during a pounce to pounce straight through mobs. It's not very practical or useful though. -Pouncing someone who is buckled to a chair will still stun them, but you won't jump into their tile and they will not be knocked to the grund. -Starshell dust from said grenades is just as meltable as normal flares. -You can join the hive as a living facehugger by clicking on the hive's eggmorpher. This works on other hives too.. -Playable facehuggers can leap onto targets with a one-second windup, but this will only infect them if they are adjacent to it. Otherwise, it will simply knock them down for a small duration. -As a facehugger, you cannot talk in hivemind, but you can still open Hive Status and overwatch your sisters. This can be useful if you're locating other facehuggers, flanker castes, or trying to learn from experienced facehugger players. +You may rest immediately during a pounce to pounce straight through mobs. It's not very practical or useful though. +Pouncing someone who is buckled to a chair will still stun them, but you won't jump into their tile and they will not be knocked to the ground. +Star shell dust from said grenades is just as meltable as normal flares. +You can join the hive as a living Facehugger by clicking on the hive's Eggmorpher. This works on other hives too.. +Playable Facehuggers can leap onto targets with a one-second windup, but this will only infect them if they are adjacent to it. Otherwise, it will simply knock them down for a small duration. +As a Facehugger, you cannot talk in hivemind, but you can still open Hive Status and overwatch your sisters. This can be useful if you're locating other Facehuggers, flanker castes, or trying to learn from experienced Facehugger players. Shift-clicking the Queen indicator will tell you what area you are in, on the map. -Resisting on a water tile will inmediately put out fires. Make sure you're alone though - It's usually better to let a friendly Xenomorph pat you out than it is to expose yourself to open water. +Resisting on a water tile will immediately put out fires. Make sure you're alone though - It's usually better to let a friendly Xenomorph pat you out than it is to expose yourself to open water. You can filter out the Xenomorphs displayed in hive status by health, allowing you to look only for wounded sisters. From cb4b498f1d2c5cca0df2515c69ae664cb49e9a86 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sun, 25 Jun 2023 06:30:08 +0100 Subject: [PATCH 44/54] Automatic changelog for PR #3707 [ci skip] --- html/changelogs/AutoChangeLog-pr-3707.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3707.yml diff --git a/html/changelogs/AutoChangeLog-pr-3707.yml b/html/changelogs/AutoChangeLog-pr-3707.yml new file mode 100644 index 000000000000..2dc44cc870d0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3707.yml @@ -0,0 +1,4 @@ +author: "blackdragonTOW" +delete-after: True +changes: + - spellcheck: "multiple typos and grammar changes in the round start tooltips." \ No newline at end of file From 2fe028d2d0163b57586e51de6c2eed2bc55d480f Mon Sep 17 00:00:00 2001 From: Zonespace <41448081+Zonespace27@users.noreply.github.com> Date: Sat, 24 Jun 2023 22:07:59 -0700 Subject: [PATCH 45/54] [s] Require affirmative input from the admin to run sdql2 verbs (#3710) "Powerful or dangerous admin verbs should have some prompt or forced runtime input to lower the attack surface once somebody finds a href exploit since topics can trigger commands and verbs." Thanks MSO https://github.com/tgstation/tgstation/pull/76276 --- code/modules/admin/verbs/SDQL2/SDQL_2.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index 52aae50a966a..c7a7664af3e8 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -203,6 +203,9 @@ message_admins(SPAN_DANGER("ERROR: Non-admin [key_name(usr)] attempted to execute a SDQL query!")) log_admin("non-admin attempted to execute a SDQL query!") return FALSE + var/prompt = tgui_alert(usr, "Run SDQL2 Query?", "SDQL2", list("Yes", "Cancel")) + if (prompt != "Yes") + return var/list/results = world.SDQL2_query(query_text, key_name_admin(usr), "[key_name(usr)]") if(length(results) == 3) for(var/I in 1 to 3) From 5cc268b66434e823cd45ae250aa04270edb7088f Mon Sep 17 00:00:00 2001 From: Drathek <76988376+Drulikar@users.noreply.github.com> Date: Sat, 24 Jun 2023 22:08:22 -0700 Subject: [PATCH 46/54] Fix larva doubling when banished and returned to core (#3708) # About the pull request This PR fixes an oversight brought up by TheGamer01 where banishing larva can double stored larva because banishment rewards it on death, and if there is still a body that body can also be returned to core. Now returning banished larva just has the same to_chat and effect as regular larva, but there is no additional larva granted. Also note that readmitting a dead xeno doesn't change the banished status on the mob (if you want to test be sure to set the ckey of the mob to something other than you). # Explain why it's good for the game No exploiting banishment please. # Testing Photographs and Procedure
Screenshots & Videos ![larba](https://github.com/cmss13-devs/cmss13/assets/76988376/1e8c40bf-66bd-4a65-9e8c-a7793aa886e6)
# Changelog :cl: Drathek fix: Fix a possibility of banished larva refunding double the larva /:cl: --- .../cm_aliens/structures/special/pylon_core.dm | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/code/modules/cm_aliens/structures/special/pylon_core.dm b/code/modules/cm_aliens/structures/special/pylon_core.dm index 40b4ad8e1718..11a0b0de597f 100644 --- a/code/modules/cm_aliens/structures/special/pylon_core.dm +++ b/code/modules/cm_aliens/structures/special/pylon_core.dm @@ -136,12 +136,14 @@ // Handle spawning larva if core is connected to a hive if(linked_hive) - for(var/mob/living/carbon/xenomorph/larva/L in range(2, src)) - if((!L.ckey || L.stat == DEAD) && L.burrowable && (L.hivenumber == linked_hive.hivenumber) && !QDELETED(L)) - visible_message(SPAN_XENODANGER("[L] quickly burrows into \the [src].")) - linked_hive.stored_larva++ - linked_hive.hive_ui.update_burrowed_larva() - qdel(L) + for(var/mob/living/carbon/xenomorph/larva/worm in range(2, src)) + if((!worm.ckey || worm.stat == DEAD) && worm.burrowable && (worm.hivenumber == linked_hive.hivenumber) && !QDELETED(worm)) + visible_message(SPAN_XENODANGER("[worm] quickly burrows into \the [src].")) + if(!worm.banished) + // Goob job bringing her back home, but no doubling please + linked_hive.stored_larva++ + linked_hive.hive_ui.update_burrowed_larva() + qdel(worm) var/spawning_larva = can_spawn_larva() && (last_larva_time + spawn_cooldown) < world.time if(spawning_larva) From b54efadd813b61fd95afdd73e97aa375b1cc5c66 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sun, 25 Jun 2023 06:52:48 +0100 Subject: [PATCH 47/54] Automatic changelog for PR #3708 [ci skip] --- html/changelogs/AutoChangeLog-pr-3708.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3708.yml diff --git a/html/changelogs/AutoChangeLog-pr-3708.yml b/html/changelogs/AutoChangeLog-pr-3708.yml new file mode 100644 index 000000000000..7e921388ec05 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3708.yml @@ -0,0 +1,4 @@ +author: "Drathek" +delete-after: True +changes: + - bugfix: "Fix a possibility of banished larva refunding double the larva" \ No newline at end of file From 5809f189405c2bc63c67b5d15c2438aca418e30b Mon Sep 17 00:00:00 2001 From: Drathek <76988376+Drulikar@users.noreply.github.com> Date: Sat, 24 Jun 2023 22:09:41 -0700 Subject: [PATCH 48/54] Player huggers now get second dibs if they hug a player (#3706) # About the pull request This PR makes it so the ckey of a player hugger is recorded in the embryo so that they can get second dibs if/when that marine pops. The marine player still has first dibs. If they manage to get a pop this way, they forfeit any other hugs they currently have (kudos though if someone is hugging multiple marines to put this measure into effect). # Explain why it's good for the game Another incentive for playable huggers! # Testing Photographs and Procedure
Screenshots & Videos Yes I test, you should too: ![image](https://github.com/cmss13-devs/cmss13/assets/76988376/7194169b-82a1-47ad-836d-42682f102b7a)
# Changelog :cl: Drathek add: Player facehugging gets 2nd dibs on the burst (the original marine gets first dibs still) /:cl: --- code/_globalvars/lists/mobs.dm | 1 + .../mob/living/carbon/xenomorph/Embryo.dm | 26 +++++++++--- .../living/carbon/xenomorph/Facehuggers.dm | 40 ++++++++++--------- .../carbon/xenomorph/castes/Facehugger.dm | 4 +- 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 187f179094b2..e2203aadce0c 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -23,6 +23,7 @@ GLOBAL_LIST_EMPTY_TYPED(alive_human_list, /mob/living/carbon/human) // list of a GLOBAL_LIST_EMPTY_TYPED(xeno_mob_list, /mob/living/carbon/xenomorph) GLOBAL_LIST_EMPTY_TYPED(living_xeno_list, /mob/living/carbon/xenomorph) GLOBAL_LIST_EMPTY_TYPED(xeno_cultists, /mob/living/carbon/human) +GLOBAL_LIST_EMPTY_TYPED(player_embryo_list, /obj/item/alien_embryo) GLOBAL_LIST_EMPTY_TYPED(hellhound_list, /mob/living/carbon/xenomorph/hellhound) GLOBAL_LIST_EMPTY_TYPED(zombie_list, /mob/living/carbon/human) diff --git a/code/modules/mob/living/carbon/xenomorph/Embryo.dm b/code/modules/mob/living/carbon/xenomorph/Embryo.dm index a74c82026dbe..29779480f143 100644 --- a/code/modules/mob/living/carbon/xenomorph/Embryo.dm +++ b/code/modules/mob/living/carbon/xenomorph/Embryo.dm @@ -12,6 +12,8 @@ var/hivenumber = XENO_HIVE_NORMAL var/faction = FACTION_XENOMORPH var/flags_embryo = FALSE // Used in /ciphering/predator property + /// The ckey of any player hugger that made this embryo + var/hugger_ckey /obj/item/alien_embryo/Initialize(mapload, ...) . = ..() @@ -33,6 +35,7 @@ C.med_hud_set_status() STOP_PROCESSING(SSobj, src) affected_mob = null + GLOB.player_embryo_list -= src . = ..() /obj/item/alien_embryo/process() @@ -145,20 +148,33 @@ var/mob/picked // If the bursted person themselves has Xeno enabled, they get the honor of first dibs on the new larva. - if((!isyautja(affected_mob) || (isyautja(affected_mob) && prob(20))) && istype(affected_mob.buckled, /obj/structure/bed/nest)) + if((!isyautja(affected_mob) || (isyautja(affected_mob) && prob(20))) && istype(affected_mob.buckled, /obj/structure/bed/nest)) if(affected_mob.first_xeno || (affected_mob.client && affected_mob.client.prefs && (affected_mob.client.prefs.be_special & BE_ALIEN_AFTER_DEATH) && !jobban_isbanned(affected_mob, JOB_XENOMORPH))) picked = affected_mob else if(affected_mob.mind && affected_mob.mind.ghost_mob && affected_mob.client && affected_mob.client.prefs && (affected_mob.client.prefs.be_special & BE_ALIEN_AFTER_DEATH) && !jobban_isbanned(affected_mob, JOB_XENOMORPH)) picked = affected_mob.mind.ghost_mob - if(!picked) // Get a candidate from observers var/list/candidates = get_alien_candidates() - if(candidates && candidates.len) - picked = candidates[1] - message_alien_candidates(candidates, dequeued = 1) + // If they were facehugged by a player thats still in queue, they get second dibs on the new larva. + if(hugger_ckey) + for(var/mob/dead/observer/cur_obs as anything in candidates) + if(cur_obs.ckey == hugger_ckey) + picked = cur_obs + candidates -= cur_obs + message_alien_candidates(candidates, dequeued = 0) + for(var/obj/item/alien_embryo/embryo as anything in GLOB.player_embryo_list) + if(embryo.hugger_ckey == cur_obs.ckey && embryo != src) + // Skipping src just in case an admin wants to quickly check before this thing fully deletes + // If this nulls out any embryo, wow + embryo.hugger_ckey = null + break + + if(!picked) + picked = candidates[1] + message_alien_candidates(candidates, dequeued = 1) // Spawn the larva var/mob/living/carbon/xenomorph/larva/new_xeno diff --git a/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm b/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm index 121a231b7bf8..212688c8c98f 100644 --- a/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm +++ b/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm @@ -241,46 +241,46 @@ throw_atom(target, 3, SPEED_FAST) return TRUE -/obj/item/clothing/mask/facehugger/proc/attach(mob/living/M, silent = FALSE, knockout_mod = 1) - if(attached || !can_hug(M, hivenumber)) +/obj/item/clothing/mask/facehugger/proc/attach(mob/living/living_mob, silent = FALSE, knockout_mod = 1, hugger_ckey = null) + if(attached || !can_hug(living_mob, hivenumber)) return FALSE // This is always going to be valid because of the can_hug check above - var/mob/living/carbon/human/H = M + var/mob/living/carbon/human/human = living_mob if(!silent) - H.visible_message(SPAN_DANGER("[src] leaps at [H]'s face!")) + human.visible_message(SPAN_DANGER("[src] leaps at [human]'s face!")) if(isxeno(loc)) //Being carried? Drop it var/mob/living/carbon/xenomorph/X = loc X.drop_inv_item_on_ground(src) - if(isturf(H.loc)) - forceMove(H.loc)//Just checkin + if(isturf(human.loc)) + forceMove(human.loc)//Just checkin - if(!H.handle_hugger_attachment(src)) + if(!human.handle_hugger_attachment(src)) return FALSE attached = TRUE - forceMove(H) + forceMove(human) icon_state = initial(icon_state) - H.equip_to_slot(src, WEAR_FACE) - H.update_inv_wear_mask() - H.disable_lights() - H.disable_special_items() - if(ishuman_strict(H)) - playsound(loc, H.gender == "male" ? 'sound/misc/facehugged_male.ogg' : 'sound/misc/facehugged_female.ogg' , 25, 0) - else if(isyautja(H)) + human.equip_to_slot(src, WEAR_FACE) + human.update_inv_wear_mask() + human.disable_lights() + human.disable_special_items() + if(ishuman_strict(human)) + playsound(loc, human.gender == "male" ? 'sound/misc/facehugged_male.ogg' : 'sound/misc/facehugged_female.ogg' , 25, 0) + else if(isyautja(human)) playsound(loc, 'sound/voice/pred_facehugged.ogg', 65, FALSE) if(!sterile) - if(!H.species || !(H.species.flags & IS_SYNTHETIC)) //synthetics aren't paralyzed - H.apply_effect(MIN_IMPREGNATION_TIME * 0.5 * knockout_mod, PARALYZE) //THIS MIGHT NEED TWEAKS + if(!human.species || !(human.species.flags & IS_SYNTHETIC)) //synthetics aren't paralyzed + human.apply_effect(MIN_IMPREGNATION_TIME * 0.5 * knockout_mod, PARALYZE) //THIS MIGHT NEED TWEAKS - addtimer(CALLBACK(src, PROC_REF(impregnate), H), rand(MIN_IMPREGNATION_TIME, MAX_IMPREGNATION_TIME)) + addtimer(CALLBACK(src, PROC_REF(impregnate), human, hugger_ckey), rand(MIN_IMPREGNATION_TIME, MAX_IMPREGNATION_TIME)) return TRUE -/obj/item/clothing/mask/facehugger/proc/impregnate(mob/living/carbon/human/target) +/obj/item/clothing/mask/facehugger/proc/impregnate(mob/living/carbon/human/target, hugger_ckey = null) if(!target || target.wear_mask != src) //Was taken off or something return if(SEND_SIGNAL(target, COMSIG_HUMAN_IMPREGNATE, src) & COMPONENT_NO_IMPREGNATE) @@ -295,6 +295,8 @@ if(!embryos) var/obj/item/alien_embryo/embryo = new /obj/item/alien_embryo(target) embryo.hivenumber = hivenumber + embryo.hugger_ckey = hugger_ckey + GLOB.player_embryo_list += embryo embryo.flags_embryo = flags_embryo flags_embryo = NO_FLAGS diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm index c0b57af9d3db..1b8ac2ee05dc 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm @@ -143,9 +143,9 @@ /mob/living/carbon/xenomorph/facehugger/proc/handle_hug(mob/living/carbon/human/human) var/obj/item/clothing/mask/facehugger/hugger = new /obj/item/clothing/mask/facehugger(loc, hivenumber) - var/did_hug = hugger.attach(human, TRUE, 0.5) + var/did_hug = hugger.attach(human, TRUE, 0.5, client?.ckey) if(client) - client?.player_data?.adjust_stat(PLAYER_STAT_FACEHUGS, STAT_CATEGORY_XENO, 1) + client.player_data?.adjust_stat(PLAYER_STAT_FACEHUGS, STAT_CATEGORY_XENO, 1) var/area/hug_area = get_area(src) if(hug_area) for(var/mob/dead/observer/observer as anything in GLOB.observer_list) From fc69adad1ea4ae89dc47c1216f4032f203c84493 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sun, 25 Jun 2023 07:08:29 +0100 Subject: [PATCH 49/54] Automatic changelog for PR #3706 [ci skip] --- html/changelogs/AutoChangeLog-pr-3706.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3706.yml diff --git a/html/changelogs/AutoChangeLog-pr-3706.yml b/html/changelogs/AutoChangeLog-pr-3706.yml new file mode 100644 index 000000000000..a63485dfdb6b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3706.yml @@ -0,0 +1,4 @@ +author: "Drathek" +delete-after: True +changes: + - rscadd: "Player facehugging gets 2nd dibs on the burst (the original marine gets first dibs still)" \ No newline at end of file From 90f14d28539c607a5bb20f0e1123ecac0b266994 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Mon, 26 Jun 2023 01:50:18 +0000 Subject: [PATCH 50/54] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-3705.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3706.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3707.yml | 4 ---- html/changelogs/AutoChangeLog-pr-3708.yml | 4 ---- html/changelogs/archive/2023-06.yml | 9 +++++++++ 5 files changed, 9 insertions(+), 16 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-3705.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3706.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3707.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-3708.yml diff --git a/html/changelogs/AutoChangeLog-pr-3705.yml b/html/changelogs/AutoChangeLog-pr-3705.yml deleted file mode 100644 index 5389f0af6869..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3705.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - bugfix: "Fixed the yank object verb not testing who is actually performing the action has a free hand" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3706.yml b/html/changelogs/AutoChangeLog-pr-3706.yml deleted file mode 100644 index a63485dfdb6b..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3706.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - rscadd: "Player facehugging gets 2nd dibs on the burst (the original marine gets first dibs still)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3707.yml b/html/changelogs/AutoChangeLog-pr-3707.yml deleted file mode 100644 index 2dc44cc870d0..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3707.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "blackdragonTOW" -delete-after: True -changes: - - spellcheck: "multiple typos and grammar changes in the round start tooltips." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3708.yml b/html/changelogs/AutoChangeLog-pr-3708.yml deleted file mode 100644 index 7e921388ec05..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3708.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - bugfix: "Fix a possibility of banished larva refunding double the larva" \ No newline at end of file diff --git a/html/changelogs/archive/2023-06.yml b/html/changelogs/archive/2023-06.yml index fafefe4203db..df1b3b34b455 100644 --- a/html/changelogs/archive/2023-06.yml +++ b/html/changelogs/archive/2023-06.yml @@ -347,3 +347,12 @@ Segrain: - bugfix: Hive core now always correctly absorbs hive's dead larvas. - bugfix: Preview dummy in character setup once again can be rotated. +2023-06-26: + Drathek: + - bugfix: Fixed the yank object verb not testing who is actually performing the + action has a free hand + - rscadd: Player facehugging gets 2nd dibs on the burst (the original marine gets + first dibs still) + - bugfix: Fix a possibility of banished larva refunding double the larva + blackdragonTOW: + - spellcheck: multiple typos and grammar changes in the round start tooltips. From 93fbc5fffa882c162aff66f0cd271969eb438671 Mon Sep 17 00:00:00 2001 From: Drathek <76988376+Drulikar@users.noreply.github.com> Date: Sun, 25 Jun 2023 19:17:31 -0700 Subject: [PATCH 51/54] Revive Fixes for Boiler: IFF Gas and Cause Data (#3577) # About the pull request This PR revives #3222 since it was basically fully complete except for a few lingering cause data issues and didn't yet address boiler gibbing gas. See linked PR or changelog for more details. See Testing Photographs and Procedure for some screenshots. The core change in this PR is that obj/effect/particle_effect/smoke/xeno_burn/Initialize now looks at the faction of the xeno that caused the smoke in the cause_data (resolve_mob would also work except for boiler gibbing smoke) to determine what faction the new smoke should be. # Explain why it's good for the game Boilers are basically unusable currently if they aren't the normal hive. The IFF fixes to the gas allow this boiler to not hurt their own hive with their abilities. # Testing Photographs and Procedure
Screenshots & Videos Some cause data examples: ![image](https://github.com/cmss13-devs/cmss13/assets/76988376/2fdfc83a-2cb6-4d78-90b5-c9609c644efd) IFF'd acid gas: ![image](https://github.com/cmss13-devs/cmss13/assets/76988376/e832d767-b8c2-4337-9557-1d89aa0ffe2f) ![image](https://github.com/cmss13-devs/cmss13/assets/76988376/687815f2-b6fd-4e10-9f3f-fd8d951e1424) Boiler gibbing gas is now IFF'd too: ![image](https://github.com/cmss13-devs/cmss13/assets/76988376/2b9cc8cb-278c-47ea-b1b3-825d086eadc2) ![image](https://github.com/cmss13-devs/cmss13/assets/76988376/1152fa9a-04fb-4788-a923-a077ba572844)
# Changelog :cl: TeDGamer Drathek fix: Boilers from other hives generate proper colored IFFed gas fix: Fixes some death causes with boiler acid gas (for bombard, shroud, and gibbing), neurotoxin gas/stabs, acid shotgun, and xeno spits balance: Neurotoxin stops processing only in dead mobs /:cl: --------- Co-authored-by: TeDGamer Co-authored-by: harryob --- code/datums/effects/neurotoxin.dm | 8 ++--- .../effects/effect_system/chemsmoke.dm | 3 +- .../objects/effects/effect_system/smoke.dm | 16 +++++----- .../abilities/boiler/boiler_powers.dm | 31 +++++++++---------- .../xenomorph/abilities/general_powers.dm | 10 +++--- .../mob/living/carbon/xenomorph/death.dm | 6 ++-- code/modules/projectiles/ammo_datums.dm | 7 +++-- 7 files changed, 41 insertions(+), 40 deletions(-) diff --git a/code/datums/effects/neurotoxin.dm b/code/datums/effects/neurotoxin.dm index 0405c87bec8b..836fccf49ca3 100644 --- a/code/datums/effects/neurotoxin.dm +++ b/code/datums/effects/neurotoxin.dm @@ -21,9 +21,8 @@ /// Stamina damage per tick. Major balance number. var/stam_dam = 7 -/datum/effects/neurotoxin/New(atom/thing) - ..(thing) - cause_data = create_cause_data("neurotoxic gas") +/datum/effects/neurotoxin/New(atom/thing, mob/from = null) + ..(thing, from, effect_name) /datum/effects/neurotoxin/validate_atom(atom/thing) if(isxeno(thing) || isobj(thing)) @@ -36,9 +35,10 @@ var/mob/living/carbon/affected_mob = affected_atom if(!.) return FALSE - if(affected_mob.stat) + if(affected_mob.stat == DEAD) return // General effects + affected_mob.last_damage_data = cause_data affected_mob.apply_stamina_damage(stam_dam) affected_mob.make_dizzy(12) diff --git a/code/game/objects/effects/effect_system/chemsmoke.dm b/code/game/objects/effects/effect_system/chemsmoke.dm index 8ecdb2c07db9..c2323c32c934 100644 --- a/code/game/objects/effects/effect_system/chemsmoke.dm +++ b/code/game/objects/effects/effect_system/chemsmoke.dm @@ -40,7 +40,8 @@ // Culls the selected turfs to a (roughly) circle shape, then calls smokeFlow() to make // sure the smoke can actually path to the turfs. This culls any turfs it can't reach. //------------------------------------------ -/datum/effect_system/smoke_spread/chem/set_up(datum/reagents/carry = null, n = 10, c = 0, loca, direct) +/datum/effect_system/smoke_spread/chem/set_up(datum/reagents/carry = null, n = 10, c = 0, loca, direct, datum/cause_data/new_cause_data) + cause_data = istype(new_cause_data) ? new_cause_data : cause_data range = n * 0.3 cardinals = c carry.copy_to(chemholder, carry.total_volume) diff --git a/code/game/objects/effects/effect_system/smoke.dm b/code/game/objects/effects/effect_system/smoke.dm index a02069087412..9f7a9c8143c7 100644 --- a/code/game/objects/effects/effect_system/smoke.dm +++ b/code/game/objects/effects/effect_system/smoke.dm @@ -283,14 +283,14 @@ var/gas_damage = 20 /obj/effect/particle_effect/smoke/xeno_burn/Initialize(mapload, amount, datum/cause_data/cause_data) - var/mob/living/carbon/xenomorph/xeno = cause_data?.resolve_mob() - if (istype(xeno) && xeno.hivenumber) - hivenumber = xeno.hivenumber - - set_hive_data(src, hivenumber) - - . = ..() + if(istype(cause_data)) + var/datum/ui_state/hive_state/cause_data_hive_state = GLOB.hive_state[cause_data.faction] + var/new_hive_number = cause_data_hive_state?.hivenumber + if(new_hive_number) + hivenumber = new_hive_number + set_hive_data(src, new_hive_number) + return ..() /obj/effect/particle_effect/smoke/xeno_burn/apply_smoke_effect(turf/T) ..() @@ -387,7 +387,7 @@ if(!issynth(moob)) var/datum/effects/neurotoxin/neuro_effect = locate() in moob.effects_list if(!neuro_effect) - neuro_effect = new /datum/effects/neurotoxin(moob) + neuro_effect = new(moob, cause_data.resolve_mob()) neuro_effect.strength = effect_amt neuro_effect.duration += neuro_dose if(moob.coughedtime != 1 && !moob.stat) //Coughing/gasping diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm index e745e8940063..dff6c82efbf8 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm @@ -139,7 +139,8 @@ spicy_gas = new /datum/effect_system/smoke_spread/xeno_weaken else CRASH("Globber has unknown ammo [xeno.ammo]! Oh no!") - spicy_gas.set_up(1, 0, get_turf(xeno), null, 6) + var/datum/cause_data/cause_data = create_cause_data("acid shroud gas", owner) + spicy_gas.set_up(1, 0, get_turf(xeno), null, 6, new_cause_data = cause_data) spicy_gas.start() to_chat(xeno, SPAN_XENOHIGHDANGER("You dump your acid through your pores, creating a shroud of gas!")) for (var/action_type in action_types_to_cd) @@ -166,9 +167,9 @@ if(!actually_moving) return - var/obj/effect/particle_effect/smoke/S = new /obj/effect/particle_effect/smoke/xeno_burn(get_turf(mover), 1, create_cause_data(initial(mover.caste_type), mover)) - S.time_to_live = 3 - S.spread_speed = 1000000 + var/obj/effect/particle_effect/smoke/xeno_burn/smoke_effect = new(get_turf(mover), 1, create_cause_data("dumped acid gas", mover)) + smoke_effect.time_to_live = 3 + smoke_effect.spread_speed = 1000000 /datum/action/xeno_action/onclick/dump_acid/remove_from() remove_speed_buff() @@ -283,27 +284,25 @@ apply_cooldown() return ..() -/datum/action/xeno_action/activable/acid_shotgun/use_ability(atom/A) - var/mob/living/carbon/xenomorph/X = owner - if (!istype(X)) +/datum/action/xeno_action/activable/acid_shotgun/use_ability(atom/target) + var/mob/living/carbon/xenomorph/xeno = owner + if (!istype(xeno)) return if (!action_cooldown_check()) return - if(!A || A.layer >= FLY_LAYER || !isturf(X.loc) || !X.check_state()) + if(!target || target.layer >= FLY_LAYER || !isturf(xeno.loc) || !xeno.check_state()) return - X.visible_message(SPAN_XENOWARNING("The [X] fires a blast of acid at [A]!"), SPAN_XENOWARNING("You fire a blast of acid at [A]!")) - - var/turf/target = locate(A.x, A.y, A.z) - var/obj/item/projectile/P = new /obj/item/projectile(X.loc, create_cause_data(initial(X.caste_type), X)) + xeno.visible_message(SPAN_XENOWARNING("The [xeno] fires a blast of acid at [target]!"), SPAN_XENOWARNING("You fire a blast of acid at [target]!")) + var/turf/target_turf = locate(target.x, target.y, target.z) + var/obj/item/projectile/proj = new(xeno.loc, create_cause_data("acid shotgun", xeno)) var/datum/ammo/ammoDatum = new ammo_type() - P.generate_bullet(ammoDatum) - - P.fire_at(target, X, X, ammoDatum.max_range, ammoDatum.shell_speed) + proj.generate_bullet(ammoDatum) + proj.fire_at(target_turf, xeno, xeno, ammoDatum.max_range, ammoDatum.shell_speed) apply_cooldown() return ..() @@ -347,7 +346,7 @@ else if(stabbing_xeno.ammo == GLOB.ammo_list[/datum/ammo/xeno/boiler_gas]) var/datum/effects/neurotoxin/neuro_effect = locate() in carbon_target.effects_list if(!neuro_effect) - neuro_effect = new /datum/effects/neurotoxin(carbon_target) + neuro_effect = new(carbon_target, owner) neuro_effect.duration += 16 to_chat(carbon_target,SPAN_HIGHDANGER("You are injected with something from [stabbing_xeno]'s tailstab!")) else diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm index dd9051ab0279..692fa31c72e7 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm @@ -760,12 +760,12 @@ SPAN_XENOWARNING("You spit a [xeno.ammo.name] at [atom]!") ) playsound(xeno.loc, sound_to_play, 25, 1) + var/obj/item/projectile/proj = new (current_turf, create_cause_data(xeno.ammo.name, xeno)) + proj.generate_bullet(xeno.ammo) + proj.permutated += xeno + proj.def_zone = xeno.get_limbzone_target() + proj.fire_at(spit_target, xeno, xeno, xeno.ammo.max_range, xeno.ammo.shell_speed) - var/obj/item/projectile/Proj = new (current_turf, create_cause_data(initial(xeno.caste_type), xeno)) - Proj.generate_bullet(xeno.ammo) - Proj.permutated += xeno - Proj.def_zone = xeno.get_limbzone_target() - Proj.fire_at(spit_target, xeno, xeno, xeno.ammo.max_range, xeno.ammo.shell_speed) spitting = FALSE SEND_SIGNAL(xeno, COMSIG_XENO_POST_SPIT) diff --git a/code/modules/mob/living/carbon/xenomorph/death.dm b/code/modules/mob/living/carbon/xenomorph/death.dm index f3534318f673..182d3d965832 100644 --- a/code/modules/mob/living/carbon/xenomorph/death.dm +++ b/code/modules/mob/living/carbon/xenomorph/death.dm @@ -138,10 +138,10 @@ switch(caste.caste_type) //This will need to be changed later, when we have proper xeno pathing. Might do it on caste or something. if(XENO_CASTE_BOILER) - var/mob/living/carbon/xenomorph/boiler/B = src + var/mob/living/carbon/xenomorph/boiler/src_boiler = src visible_message(SPAN_DANGER("[src] begins to bulge grotesquely, and explodes in a cloud of corrosive gas!")) - B.smoke.set_up(2, 0, get_turf(src)) - B.smoke.start() + src_boiler.smoke.set_up(2, 0, get_turf(src), new_cause_data = src_boiler.smoke.cause_data) + src_boiler.smoke.start() remains.icon_state = "gibbed-a-corpse" if(XENO_CASTE_RUNNER) remains.icon_state = "gibbed-a-corpse-runner" diff --git a/code/modules/projectiles/ammo_datums.dm b/code/modules/projectiles/ammo_datums.dm index 05a4256efb49..d8b158485501 100644 --- a/code/modules/projectiles/ammo_datums.dm +++ b/code/modules/projectiles/ammo_datums.dm @@ -2740,7 +2740,7 @@ return var/datum/effects/neurotoxin/neuro_effect = locate() in moob.effects_list if(!neuro_effect) - neuro_effect = new /datum/effects/neurotoxin(moob) + neuro_effect = new /datum/effects/neurotoxin(moob, proj.firer) neuro_effect.duration += 5 moob.apply_effect(3, DAZE) to_chat(moob, SPAN_HIGHDANGER("Neurotoxic liquid spreads all over you and immediately soaks into your pores and orifices! Oh fuck!")) // Fucked up but have a chance to escape rather than being game-ended @@ -2763,9 +2763,10 @@ /datum/ammo/xeno/boiler_gas/proc/drop_nade(turf/turf, obj/item/projectile/proj) var/lifetime_mult = 1.0 + var/datum/cause_data if(isboiler(proj.firer)) - smoke_system.cause_data = proj.weapon_cause_data - smoke_system.set_up(smokerange, 0, turf) + cause_data = proj.weapon_cause_data + smoke_system.set_up(smokerange, 0, turf, new_cause_data = cause_data) smoke_system.lifetime = 12 * lifetime_mult smoke_system.start() turf.visible_message(SPAN_DANGER("A glob of acid lands with a splat and explodes into noxious fumes!")) From b18014ae1a3f1e6d4535fdb72f82d04f07784ac1 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Mon, 26 Jun 2023 03:25:42 +0100 Subject: [PATCH 52/54] Automatic changelog for PR #3577 [ci skip] --- html/changelogs/AutoChangeLog-pr-3577.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3577.yml diff --git a/html/changelogs/AutoChangeLog-pr-3577.yml b/html/changelogs/AutoChangeLog-pr-3577.yml new file mode 100644 index 000000000000..759df8eb0357 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3577.yml @@ -0,0 +1,6 @@ +author: "TeDGamer Drathek" +delete-after: True +changes: + - bugfix: "Boilers from other hives generate proper colored IFFed gas" + - bugfix: "Fixes some death causes with boiler acid gas (for bombard, shroud, and gibbing), neurotoxin gas/stabs, acid shotgun, and xeno spits" + - balance: "Neurotoxin stops processing only in dead mobs" \ No newline at end of file From 8db4763123976b7421458d02d07e27ccad6b42c6 Mon Sep 17 00:00:00 2001 From: TheGamerdk <5618080+TheGamerdk@users.noreply.github.com> Date: Mon, 26 Jun 2023 21:00:40 +0200 Subject: [PATCH 53/54] Fixes a typo that made the game think there's not a CO onboard. (#3722) # About the pull request Officer, not Officers # Explain why it's good for the game # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
bugs bad # Changelog :cl: fix: The game will no longer falsely claim there is no CO /:cl: --------- Co-authored-by: harryob --- code/controllers/subsystem/ticker.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 58910c45af75..0e23b99a9cc2 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -424,7 +424,7 @@ SUBSYSTEM_DEF(ticker) for(var/mob/living/carbon/human/player in GLOB.human_mob_list) if(player.mind) - if(player.job == "Commanding Officers") + if(player.job == JOB_CO) captainless = FALSE if(player.job) RoleAuthority.equip_role(player, RoleAuthority.roles_by_name[player.job], late_join = FALSE) From 62ad790be0e49150495fbac8fc128bfd454d005a Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Mon, 26 Jun 2023 20:10:32 +0100 Subject: [PATCH 54/54] Automatic changelog for PR #3722 [ci skip] --- html/changelogs/AutoChangeLog-pr-3722.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3722.yml diff --git a/html/changelogs/AutoChangeLog-pr-3722.yml b/html/changelogs/AutoChangeLog-pr-3722.yml new file mode 100644 index 000000000000..f915061d5db7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3722.yml @@ -0,0 +1,4 @@ +author: "TheGamerdk" +delete-after: True +changes: + - bugfix: "The game will no longer falsely claim there is no CO" \ No newline at end of file