diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index acb6d26bf0d5..1a440d41bbed 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -64,7 +64,14 @@ /obj/structure/machinery/camera/update_icon() . = ..() - if(icon_state == "autocam_editor") + // If the camera has been EMPed. + if(stat & EMPED) + icon_state = "cameraemp" + // If the camera isn't EMPed, but is disabled. + else if(!status) + icon_state = "camera1" + // Otherwise, just give it the normal animated `icon_state`. + else icon_state = "camera" /obj/structure/machinery/camera/set_pixel_location() @@ -76,24 +83,27 @@ /obj/structure/machinery/camera/emp_act(severity) . = ..() - if(!isEmpProof()) - if(prob(100/severity)) - icon_state = "[initial(icon_state)]emp" - var/list/previous_network = network - network = list() - GLOB.cameranet.removeCamera(src) - stat |= EMPED - set_light(0) - triggerCameraAlarm() - spawn(900) - network = previous_network - icon_state = initial(icon_state) - stat &= ~EMPED - cancelCameraAlarm() - if(can_use()) - GLOB.cameranet.addCamera(src) - kick_viewers() + // If the camera is EMP proof, or it passed the RNG check. + if(isEmpProof() || !prob(100 / severity)) + return + + var/list/previous_network = network + network = list() + GLOB.cameranet.removeCamera(src) + stat |= EMPED + update_icon() + set_light(0) + triggerCameraAlarm() + kick_viewers() + addtimer(CALLBACK(src, PROC_REF(undo_emp), previous_network), 90 SECONDS) +/obj/structure/machinery/camera/proc/undo_emp(previous_network) + network = previous_network + stat &= ~EMPED + update_icon() + cancelCameraAlarm() + if(can_use()) + GLOB.cameranet.addCamera(src) /obj/structure/machinery/camera/ex_act(severity) if(src.invuln) @@ -189,10 +199,7 @@ visible_message(SPAN_WARNING("[user] has reactivated [src]!")) else visible_message(SPAN_WARNING("[user] has deactivated [src]!")) - if(status) - icon_state = "camera" - else - icon_state = "camera1" + update_icon() // now disconnect anyone using the camera //Apparently, this will disconnect anyone even if the camera was re-activated. //I guess that doesn't matter since they can't use it anyway? diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 0b44c0bb4443..d328bb958643 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -489,30 +489,33 @@ /obj/effect/xenomorph/xeno_telegraph name = "???" desc = "" - icon_state = "xeno_telegraph_red" + icon_state = "xeno_telegraph_base" mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/obj/effect/xenomorph/xeno_telegraph/New(loc, ttl = 10) +/// Icon is by default a white sprite, provide an rgb hex code #RRGGBB argument to change. +/obj/effect/xenomorph/xeno_telegraph/New(loc, ttl = 10, color = null) ..(loc) + if(color) + src.color = color QDEL_IN(src, ttl) /obj/effect/xenomorph/xeno_telegraph/red - icon_state = "xeno_telegraph_red" + color = COLOUR_DARK_RED /obj/effect/xenomorph/xeno_telegraph/brown - icon_state = "xeno_telegraph_brown" + color = COLOUR_BROWN /obj/effect/xenomorph/xeno_telegraph/green - icon_state = "xeno_telegraph_green" + color = COLOUR_GREEN -/obj/effect/xenomorph/xeno_telegraph/brown/abduct_hook +/// This has a brown icon state and does not have a color overlay by default. +/obj/effect/xenomorph/xeno_telegraph/abduct_hook icon_state = "xeno_telegraph_abduct_hook_anim" -/obj/effect/xenomorph/xeno_telegraph/brown/lash +/// This has a brown icon state and does not have a color overlay by default. +/obj/effect/xenomorph/xeno_telegraph/lash icon_state = "xeno_telegraph_lash" - - /obj/effect/xenomorph/acid_damage_delay name = "???" desc = "" diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index c4a4fd61cd78..3d0471a48253 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -57,11 +57,12 @@ return set_light_on(toggle_on) - if(user == loc) - user.update_inv_head() update_icon() + if(user == loc) + user.update_inv_head() + for(var/datum/action/current_action as anything in actions) current_action.update_button_icon() diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index b171b4ed934f..dd540033b2a2 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -2,11 +2,14 @@ /obj/item/clothing/head/helmet/space/santahat name = "Santa's hat" desc = "Ho ho ho. Merrry X-mas!" - icon_state = "santahat" + icon_state = "santa_hat_red" flags_inventory = NOPRESSUREDMAGE|BLOCKSHARPOBJ flags_inv_hide = HIDEEYES flags_armor_protection = BODY_FLAG_HEAD +/obj/item/clothing/head/helmet/space/santahat/green + icon_state = "santa_hat_green" + /obj/item/clothing/suit/space/santa name = "Santa's suit" desc = "Festive!" diff --git a/code/modules/cm_marines/Donator_Items.dm b/code/modules/cm_marines/Donator_Items.dm index 6d2f46490d13..72cfa9724ebd 100644 --- a/code/modules/cm_marines/Donator_Items.dm +++ b/code/modules/cm_marines/Donator_Items.dm @@ -587,7 +587,7 @@ /obj/item/clothing/head/helmet/marine/fluff/santahat //CKEY=tophatpenguin name = "Santa's hat" desc = "Ho ho ho. Merrry X-mas!" - icon_state = "santahat" + icon_state = "santa_hat_red" flags_inventory = BLOCKSHARPOBJ flags_inv_hide = HIDEEARS|HIDEALLHAIR diff --git a/code/modules/decorators/christmas.dm b/code/modules/decorators/christmas.dm index 2a87c7cb494d..5c4126510056 100644 --- a/code/modules/decorators/christmas.dm +++ b/code/modules/decorators/christmas.dm @@ -49,10 +49,12 @@ helmet.desc = "Ho ho ho, Merry Christmas!" helmet.icon = 'icons/obj/items/clothing/hats.dmi' helmet.icon_override = 'icons/mob/humans/onmob/head_0.dmi' - helmet.icon_state = "santahat" - helmet.flags_inventory = BLOCKSHARPOBJ helmet.flags_inv_hide = HIDEEARS|HIDEALLHAIR helmet.flags_marine_helmet = NO_FLAGS + if(prob(50)) + helmet.icon_state = "santa_hat_red" + else + helmet.icon_state = "santa_hat_green" helmet.update_icon() // barricade definition. Also only a single definition diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm index 35226c7a1956..d724d662ae29 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm @@ -280,7 +280,7 @@ turflist += turf facing = get_dir(turf, atom) - telegraph_atom_list += new /obj/effect/xenomorph/xeno_telegraph/brown/abduct_hook(turf, windup) + telegraph_atom_list += new /obj/effect/xenomorph/xeno_telegraph/abduct_hook(turf, windup) if(!length(turflist)) to_chat(xeno, SPAN_XENOWARNING("We don't have any room to do our abduction!")) @@ -468,14 +468,14 @@ continue target_turfs += T - telegraph_atom_list += new /obj/effect/xenomorph/xeno_telegraph/brown/lash(T, windup) + telegraph_atom_list += new /obj/effect/xenomorph/xeno_telegraph/lash(T, windup) var/turf/next_turf = get_step(T, facing) if (!istype(next_turf) || next_turf.density) continue target_turfs += next_turf - telegraph_atom_list += new /obj/effect/xenomorph/xeno_telegraph/brown/lash(next_turf, windup) + telegraph_atom_list += new /obj/effect/xenomorph/xeno_telegraph/lash(next_turf, windup) if(!length(target_turfs)) to_chat(X, SPAN_XENOWARNING("We don't have any room to do our tail lash!")) diff --git a/html/changelogs/AutoChangeLog-pr-5027.yml b/html/changelogs/AutoChangeLog-pr-5027.yml deleted file mode 100644 index e7927d51b587..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5027.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "LTNTS" -delete-after: True -changes: - - maptweak: "remapped brig to be more concise, more interconnected, and easier to navigate. And added more cells for when needed." - - qol: "adds RiotTech (SecTech but for Riot Control with Rubber Bullets - obvs Code Blue+ only)" - - qol: "CMP's locker requires Armory access to open now" - - qol: "suspects are now colored nardo gray in security list" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5155.yml b/html/changelogs/AutoChangeLog-pr-5155.yml new file mode 100644 index 000000000000..0723bfe963a4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5155.yml @@ -0,0 +1,5 @@ +author: "GoldenAlpharex" +delete-after: True +changes: + - bugfix: "Chat highlights now escape special RegEx characters from non-RegEx highlights." + - bugfix: "Broken RegEx expressions no longer cause the chat to bluescreen, allowing you to properly fix them." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5180.yml b/html/changelogs/AutoChangeLog-pr-5180.yml deleted file mode 100644 index a4f8d5ded55c..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5180.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - bugfix: "Fix dead nested mobs disappearing when weeded" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5200.yml b/html/changelogs/AutoChangeLog-pr-5200.yml deleted file mode 100644 index a31a5a94db0f..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5200.yml +++ /dev/null @@ -1,11 +0,0 @@ -author: "Triiodine" -delete-after: True -changes: - - rscadd: "randomized barrels for mappers. You can instance the straps on and off!" - - imageadd: "Resprited the following: traffic cone, goldschlager bottle, cream carton, oj carton, lime juice carton, tomato juice carton, pineapple juice carton, tequila bottle, kahlua bottle, bottle of nothing, cognac bottle, critter crate (now lore accurate), secgear crate, cm barrels, phoron crate, riot shield inhands," - - imageadd: "Added unique sprites for the following: vodka bottle, gin bottle," - - imageadd: "Fixed stray pixels on fridgeopen, open_plastic" - - imagedel: "Removed some unused legacy icons." - - bugfix: "Hotdogs and burritos now properly appear when worn in a helmet in packaged and unpackaged states." - - imageadd: "The ME3 hand welder and industrial welder now have unique sprites and inhands." - - imageadd: "Differentiates synth graft and surgical line, color coded now to represent the damage they fix." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5207.yml b/html/changelogs/AutoChangeLog-pr-5207.yml new file mode 100644 index 000000000000..c170ccbcecb9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5207.yml @@ -0,0 +1,4 @@ +author: "Birdtalon" +delete-after: True +changes: + - rscadd: "Xenomorph telegraph effects can now be any rgb colour." \ No newline at end of file diff --git a/html/changelogs/archive/2023-12.yml b/html/changelogs/archive/2023-12.yml index 468497c8de76..984b339c718e 100644 --- a/html/changelogs/archive/2023-12.yml +++ b/html/changelogs/archive/2023-12.yml @@ -264,3 +264,34 @@ out of the toss mid-flight. realforest2001: - bugfix: M56D can no longer be used by the dead. +2023-12-15: + BeagleGaming1: + - imageadd: New sprite for Santa hats + Drathek: + - bugfix: Fix dead nested mobs disappearing when weeded + LTNTS: + - maptweak: remapped brig to be more concise, more interconnected, and easier to + navigate. And added more cells for when needed. + - qol: adds RiotTech (SecTech but for Riot Control with Rubber Bullets - obvs Code + Blue+ only) + - qol: CMP's locker requires Armory access to open now + - qol: suspects are now colored nardo gray in security list + NateDross: + - bugfix: Fixed hard hat user inventory head icon + SabreML: + - bugfix: Fixed camera sprites changing to their mapping helper after being EMPed. + Triiodine: + - rscadd: randomized barrels for mappers. You can instance the straps on and off! + - imageadd: 'Resprited the following: traffic cone, goldschlager bottle, cream carton, + oj carton, lime juice carton, tomato juice carton, pineapple juice carton, tequila + bottle, kahlua bottle, bottle of nothing, cognac bottle, critter crate (now + lore accurate), secgear crate, cm barrels, phoron crate, riot shield inhands,' + - imageadd: 'Added unique sprites for the following: vodka bottle, gin bottle,' + - imageadd: Fixed stray pixels on fridgeopen, open_plastic + - imagedel: Removed some unused legacy icons. + - bugfix: Hotdogs and burritos now properly appear when worn in a helmet in packaged + and unpackaged states. + - imageadd: The ME3 hand welder and industrial welder now have unique sprites and + inhands. + - imageadd: Differentiates synth graft and surgical line, color coded now to represent + the damage they fix. diff --git a/icons/mob/humans/onmob/head_0.dmi b/icons/mob/humans/onmob/head_0.dmi index 51cad85586e7..f1d6a2c6e665 100644 Binary files a/icons/mob/humans/onmob/head_0.dmi and b/icons/mob/humans/onmob/head_0.dmi differ diff --git a/icons/mob/xenos/effects.dmi b/icons/mob/xenos/effects.dmi index 80cc35fde5ba..132c5f78b0d7 100644 Binary files a/icons/mob/xenos/effects.dmi and b/icons/mob/xenos/effects.dmi differ diff --git a/icons/obj/items/clothing/hats.dmi b/icons/obj/items/clothing/hats.dmi index a6a0e6fb9099..de6673d07b51 100644 Binary files a/icons/obj/items/clothing/hats.dmi and b/icons/obj/items/clothing/hats.dmi differ diff --git a/tgui/packages/tgui-panel/chat/renderer.js b/tgui/packages/tgui-panel/chat/renderer.js index f7ce9277cf68..fe175ee6d94e 100644 --- a/tgui/packages/tgui-panel/chat/renderer.js +++ b/tgui/packages/tgui-panel/chat/renderer.js @@ -193,6 +193,7 @@ class ChatRenderer { const matchWord = setting.matchWord; const matchCase = setting.matchCase; const allowedRegex = /^[a-z0-9_\-$/^[\s\]\\]+$/gi; + const regexEscapeCharacters = /[!#$%^&*)(+=.<>{}[\]:;'"|~`_\-\\/]/g; const lines = String(text) .split(',') .map((str) => str.trim()) @@ -228,19 +229,27 @@ class ChatRenderer { if (!highlightWords) { highlightWords = []; } + // We're not going to let regex characters fuck up our RegEx operation. + line = line.replace(regexEscapeCharacters, '\\$&'); + highlightWords.push(line); } } - const regexStr = regexExpressions.join('|'); - const flags = 'g' + (matchCase ? '' : 'i'); - // setting regex overrides matchword - if (regexStr) { - highlightRegex = new RegExp('(' + regexStr + ')', flags); - } else { - const pattern = `${matchWord ? '\\b' : ''}(${lines.join('|')})${ - matchWord ? '\\b' : '' - }`; - highlightRegex = new RegExp(pattern, flags); + // We wrap this in a try-catch to ensure that broken regex doesn't break + // the entire chat. + try { + // setting regex overrides matchword + if (regexStr) { + highlightRegex = new RegExp('(' + regexStr + ')', flags); + } else { + const pattern = `${matchWord ? '\\b' : ''}(${highlightWords.join( + '|' + )})${matchWord ? '\\b' : ''}`; + highlightRegex = new RegExp(pattern, flags); + } + } catch { + // We just reset it if it's invalid. + highlightRegex = null; } // Lazy init if (!this.highlightParsers) {