diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 7d1302ef8f2..a3b35e6c894 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -86,6 +86,9 @@
if (.)
return
+ if (!has_communication())
+ return
+
. = TRUE
switch (action)
@@ -323,6 +326,7 @@
var/list/data = list(
"authenticated" = FALSE,
"emagged" = FALSE,
+ "hasConnection" = has_communication(),
)
var/ui_state = issilicon(user) ? cyborg_state : state
@@ -436,6 +440,12 @@
"maxMessageLength" = MAX_MESSAGE_LEN,
)
+/// Returns whether or not the communications console can communicate with the station
+/obj/machinery/computer/communications/proc/has_communication()
+ var/turf/current_turf = get_turf(src)
+ var/z_level = current_turf.z
+ return is_station_level(z_level) || is_centcom_level(z_level)
+
/obj/machinery/computer/communications/proc/set_state(mob/user, new_state)
if (issilicon(user))
cyborg_state = new_state
@@ -496,7 +506,6 @@
frequency.post_signal(src, status_signal)
-
/obj/machinery/computer/communications/Destroy()
GLOB.shuttle_caller_list -= src
SSshuttle.autoEvac()
diff --git a/tgui/packages/tgui/components/Blink.js b/tgui/packages/tgui/components/Blink.js
new file mode 100644
index 00000000000..1f1fd908318
--- /dev/null
+++ b/tgui/packages/tgui/components/Blink.js
@@ -0,0 +1,65 @@
+import { Component } from 'inferno';
+
+const DEFAULT_BLINKING_INTERVAL = 1000;
+const DEFAULT_BLINKING_TIME = 1000;
+
+export class Blink extends Component {
+ constructor() {
+ super();
+ this.state = {
+ hidden: false,
+ };
+ }
+
+ createTimer() {
+ const {
+ interval = DEFAULT_BLINKING_INTERVAL,
+ time = DEFAULT_BLINKING_TIME,
+ } = this.props;
+
+ clearInterval(this.interval);
+ clearTimeout(this.timer);
+
+ this.setState({
+ hidden: false,
+ });
+
+ this.interval = setInterval(() => {
+ this.setState({
+ hidden: true,
+ });
+
+ this.timer = setTimeout(() => {
+ this.setState({
+ hidden: false,
+ });
+ }, time);
+ }, interval + time);
+ }
+
+ componentDidMount() {
+ this.createTimer();
+ }
+
+ componentDidUpdate(prevProps) {
+ if (prevProps.interval !== this.props.interval
+ || prevProps.time !== this.props.time) {
+ this.createTimer();
+ }
+ }
+
+ componentWillUnmount() {
+ clearInterval(this.interval);
+ clearTimeout(this.timer);
+ }
+
+ render(props) {
+ return (
+
+ {props.children}
+
+ );
+ }
+}
diff --git a/tgui/packages/tgui/components/index.js b/tgui/packages/tgui/components/index.js
index 9a4406b17c3..2e4ed48b9c8 100644
--- a/tgui/packages/tgui/components/index.js
+++ b/tgui/packages/tgui/components/index.js
@@ -5,6 +5,7 @@
*/
export { AnimatedNumber } from './AnimatedNumber';
+export { Blink } from './Blink';
export { BlockQuote } from './BlockQuote';
export { Box } from './Box';
export { Button } from './Button';
diff --git a/tgui/packages/tgui/debug/KitchenSink.js b/tgui/packages/tgui/debug/KitchenSink.js
index 6b7fb7097a9..f25869b80b6 100644
--- a/tgui/packages/tgui/debug/KitchenSink.js
+++ b/tgui/packages/tgui/debug/KitchenSink.js
@@ -6,7 +6,7 @@
import { Fragment } from 'inferno';
import { useBackend, useLocalState } from '../backend';
-import { BlockQuote, Box, Button, ByondUi, Collapsible, DraggableControl, Flex, Icon, Input, Knob, LabeledList, NoticeBox, NumberInput, ProgressBar, Section, Slider, Tabs, Tooltip } from '../components';
+import { Blink, BlockQuote, Box, Button, ByondUi, Collapsible, DraggableControl, Flex, Icon, Input, Knob, LabeledList, NoticeBox, NumberInput, ProgressBar, Section, Slider, Tabs, Tooltip } from '../components';
import { formatSiUnit } from '../format';
import { Pane, Window } from '../layouts';
import { createLogger } from '../logging';
@@ -41,6 +41,10 @@ const PAGES = [
title: 'Button',
component: () => KitchenSinkButton,
},
+ {
+ title: 'Blink',
+ component: () => KitchenSinkBlinker,
+ },
{
title: 'Box',
component: () => KitchenSinkBox,
@@ -175,6 +179,16 @@ const KitchenSinkButton = props => {
);
};
+const KitchenSinkBlinker = props => {
+ return (
+ "+e+"
/gi,"\n").replace(/<\/?[a-z0-9-_]+[^>]*>/gi,"").replace(/&(nbsp|amp|quot|lt|gt|apos);/g,(function(e,n){return t[n]})).replace(/?([0-9]+);/gi,(function(e,t){var n=parseInt(t,10);return String.fromCharCode(n)})).replace(/?([0-9a-f]+);/gi,(function(e,t){var n=parseInt(t,16);return String.fromCharCode(n)}))};t.buildQueryString=function(e){return Object.keys(e).map((function(t){return encodeURIComponent(t)+"="+encodeURIComponent(e[t])})).join("&")}},function(e,t,n){"use strict";t.__esModule=!0,t.Box=t.computeBoxClassName=t.computeBoxProps=t.halfUnit=t.unit=void 0;var r=n(6),o=n(0),i=n(466),a=n(42);var u=function(e){return"string"==typeof e?e.endsWith("px")&&!Byond.IS_LTE_IE8?parseFloat(e)/12+"rem":e:"number"==typeof e?Byond.IS_LTE_IE8?12*e+"px":e+"rem":void 0};t.unit=u;var c=function(e){return"string"==typeof e?u(e):"number"==typeof e?u(.5*e):void 0};t.halfUnit=c;var s=function(e){return"string"==typeof e&&a.CSS_COLORS.includes(e)},l=function(e){return function(t,n){"number"!=typeof n&&"string"!=typeof n||(t[e]=n)}},f=function(e,t){return function(n,r){"number"!=typeof r&&"string"!=typeof r||(n[e]=t(r))}},d=function(e,t){return function(n,r){r&&(n[e]=t)}},p=function(e,t,n){return function(r,o){if("number"==typeof o||"string"==typeof o)for(var i=0;ic||n!=n?l*Infinity:l*n}},function(e,t,n){"use strict";var r=n(4),o=Math.hypot,i=Math.abs,a=Math.sqrt;r({target:"Math",stat:!0,forced:!!o&&o(Infinity,NaN)!==Infinity},{hypot:function(e,t){for(var n,r,o=0,u=0,c=arguments.length,s=0;u
\n":"'+(n?e:ee(e,!0))+"
\n"}return e}(),t.blockquote=function(){function e(e){return""+(n?e:ee(e,!0))+"\n"+e+"
\n"}return e}(),t.html=function(){function e(e){return e}return e}(),t.heading=function(){function e(e,t,n,r){return this.options.headerIds?"
\n":"
\n"}return e}(),t.list=function(){function e(e,t,n){var r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+""+r+">\n"}return e}(),t.listitem=function(){function e(e){return"\n\n"+e+"\n"+t+"
\n"}return e}(),t.tablerow=function(){function e(e){return"\n"+e+" \n"}return e}(),t.tablecell=function(){function e(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' align="'+t.align+'">':"<"+n+">")+e+""+n+">\n"}return e}(),t.strong=function(){function e(e){return""+e+""}return e}(),t.em=function(){function e(e){return""+e+""}return e}(),t.codespan=function(){function e(e){return""+e+""}return e}(),t.br=function(){function e(){return this.options.xhtml?"
":"
"}return e}(),t.del=function(){function e(e){return""+e+""}return e}(),t.link=function(){function e(e,t,n){if(null===(e=J(this.options.sanitize,this.options.baseUrl,e)))return n;var r='"+n+""}return e}(),t.image=function(){function e(e,t,n){if(null===(e=J(this.options.sanitize,this.options.baseUrl,e)))return n;var r='":">"}return e}(),t.text=function(){function e(e){return e}return e}(),e}(),ne=function(){function e(){}var t=e.prototype;return t.strong=function(){function e(e){return e}return e}(),t.em=function(){function e(e){return e}return e}(),t.codespan=function(){function e(e){return e}return e}(),t.del=function(){function e(e){return e}return e}(),t.html=function(){function e(e){return e}return e}(),t.text=function(){function e(e){return e}return e}(),t.link=function(){function e(e,t,n){return""+n}return e}(),t.image=function(){function e(e,t,n){return""+n}return e}(),t.br=function(){function e(){return""}return e}(),e}(),re=function(){function e(){this.seen={}}return e.prototype.slug=function(){function e(e){var t=e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-");if(this.seen.hasOwnProperty(t)){var n=t;do{this.seen[n]++,t=n+"-"+this.seen[n]}while(this.seen.hasOwnProperty(t))}return this.seen[t]=0,t}return e}(),e}(),oe=a.defaults,ie=I.unescape,ae=function(){function e(e){this.options=e||oe,this.options.renderer=this.options.renderer||new te,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new ne,this.slugger=new re}e.parse=function(){function t(t,n){return new e(n).parse(t)}return t}();var t=e.prototype;return t.parse=function(){function e(e,t){void 0===t&&(t=!0);var n,r,o,i,a,u,c,s,l,f,d,p,h,g,v,m,y,b,x="",w=e.length;for(n=0;n
"+se(c.message+"",!0)+"";throw c}}return pe.options=pe.setOptions=function(e){return ue(pe.defaults,e),fe(pe.defaults),pe},pe.getDefaults=le,pe.defaults=de,pe.use=function(e){var t=ue({},e);if(e.renderer&&function(){var n=pe.defaults.renderer||new te,r=function(){function t(t){var r=n[t];n[t]=function(){for(var o=arguments.length,i=new Array(o),a=0;a
'+(n?e:ee(e,!0))+"\n":""+(n?e:ee(e,!0))+"\n"}return e}(),t.blockquote=function(){function e(e){return"\n"+e+"\n"}return e}(),t.html=function(){function e(e){return e}return e}(),t.heading=function(){function e(e,t,n,r){return this.options.headerIds?"
"+e+"
\n"}return e}(),t.table=function(){function e(e,t){return t&&(t=""+t+""),""+e+""}return e}(),t.br=function(){function e(){return this.options.xhtml?""+se(c.message+"",!0)+"";throw c}}return pe.options=pe.setOptions=function(e){return ue(pe.defaults,e),fe(pe.defaults),pe},pe.getDefaults=le,pe.defaults=de,pe.use=function(e){var t=ue({},e);if(e.renderer&&function(){var n=pe.defaults.renderer||new te,r=function(){function t(t){var r=n[t];n[t]=function(){for(var o=arguments.length,i=new Array(o),a=0;a