From 7429631f4bab55e54e24e055bf3b960549462378 Mon Sep 17 00:00:00 2001
From: XeonMations <62395746+XeonMations@users.noreply.github.com>
Date: Wed, 11 Sep 2024 10:20:01 +0300
Subject: [PATCH 1/9] [Port] Crew monitoring console sorting (#11363)
* this wont work but i can draft it
* hmh
* IT WORKS
---
tgui/packages/tgui/constants.js | 1 +
tgui/packages/tgui/interfaces/CrewConsole.js | 139 ----------
tgui/packages/tgui/interfaces/CrewConsole.tsx | 258 ++++++++++++++++++
3 files changed, 259 insertions(+), 139 deletions(-)
delete mode 100644 tgui/packages/tgui/interfaces/CrewConsole.js
create mode 100644 tgui/packages/tgui/interfaces/CrewConsole.tsx
diff --git a/tgui/packages/tgui/constants.js b/tgui/packages/tgui/constants.js
index 4caf607c13261..182bcd0634c7a 100644
--- a/tgui/packages/tgui/constants.js
+++ b/tgui/packages/tgui/constants.js
@@ -20,6 +20,7 @@ export const COLORS = {
science: '#9b59b6',
engineering: '#f1c40f',
cargo: '#f39c12',
+ service: '#7cc46a',
centcom: '#00c100',
other: '#c38312',
},
diff --git a/tgui/packages/tgui/interfaces/CrewConsole.js b/tgui/packages/tgui/interfaces/CrewConsole.js
deleted file mode 100644
index bf72fad4e327a..0000000000000
--- a/tgui/packages/tgui/interfaces/CrewConsole.js
+++ /dev/null
@@ -1,139 +0,0 @@
-import { useBackend } from '../backend';
-import { Box, Button, ColorBox, Section, Table } from '../components';
-import { COLORS } from '../constants';
-import { Window } from '../layouts';
-import { sortBy } from 'common/collections';
-
-export const HEALTH_COLOR_BY_LEVEL = ['#17d568', '#2ecc71', '#e67e22', '#ed5100', '#e74c3c', '#ed2814'];
-
-export const jobIsHead = (jobId) => jobId % 10 === 0;
-
-export const jobToColor = (jobId) => {
- if (jobId >= 0 && jobId < 10) {
- return COLORS.department.captain;
- }
- if (jobId >= 10 && jobId < 20) {
- return COLORS.department.security;
- }
- if (jobId >= 20 && jobId < 30) {
- return COLORS.department.medbay;
- }
- if (jobId >= 30 && jobId < 40) {
- return COLORS.department.science;
- }
- if (jobId >= 40 && jobId < 50) {
- return COLORS.department.engineering;
- }
- if (jobId >= 50 && jobId < 60) {
- return COLORS.department.cargo;
- }
- if (jobId >= 200 && jobId < 230) {
- return COLORS.department.centcom;
- }
- if (jobId === -1) {
- return null;
- }
- return COLORS.department.other;
-};
-
-export const healthToColor = (oxy, tox, burn, brute) => {
- const healthSum = oxy + tox + burn + brute;
- const level = Math.min(Math.max(Math.ceil(healthSum / 25), 0), 5);
- return HEALTH_COLOR_BY_LEVEL[level];
-};
-
-export const HealthStat = (props) => {
- const { type, value } = props;
- return (
-
- {value}
-
- );
-};
-
-export const CrewConsole = () => {
- return (
-
-
-
-
-
- );
-};
-
-const CrewTable = (props, context) => {
- const { act, data } = useBackend(context);
- const sensors = sortBy((s) => s.ijob)(data.sensors ?? []);
- return (
-
-
- Name
-
-
- Vitals
-
- Position
- {!!data.link_allowed && (
-
- Tracking
-
- )}
-
- {sensors.map((sensor) => (
-
- ))}
-
- );
-};
-
-const CrewTableEntry = (props, context) => {
- const { act, data } = useBackend(context);
- const { link_allowed } = data;
- const { sensor_data } = props;
- const { name, assignment, ijob, life_status, oxydam, toxdam, burndam, brutedam, area, can_track } = sensor_data;
-
- return (
-
-
- {name}
- {assignment !== undefined ? ` (${assignment})` : ''}
-
-
- {life_status ? : }
-
-
- {oxydam !== undefined ? (
-
-
- {'/'}
-
- {'/'}
-
- {'/'}
-
-
- ) : life_status ? (
- 'Alive'
- ) : (
- 'Dead'
- )}
-
- {area !== undefined ? area : 'N/A'}
- {!!link_allowed && (
-
-
- )}
-
- );
-};
diff --git a/tgui/packages/tgui/interfaces/CrewConsole.tsx b/tgui/packages/tgui/interfaces/CrewConsole.tsx
new file mode 100644
index 0000000000000..192eac007d4f6
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/CrewConsole.tsx
@@ -0,0 +1,258 @@
+import { Box, Button, Icon, Input, Section, Table } from '../components';
+import { BooleanLike } from 'common/react';
+import { createSearch } from 'common/string';
+import { useBackend, useLocalState } from '../backend';
+import { COLORS } from '../constants';
+import { Window } from '../layouts';
+
+const HEALTH_COLOR_BY_LEVEL = ['#17d568', '#c4cf2d', '#e67e22', '#ed5100', '#e74c3c', '#801308'];
+
+const SORT_NAMES = {
+ ijob: 'Job',
+ name: 'Name',
+ area: 'Position',
+ health: 'Vitals',
+};
+
+const STAT_LIVING = 0;
+const STAT_DEAD = 4;
+
+const SORT_OPTIONS = ['health', 'ijob', 'name', 'area'];
+
+const jobIsHead = (jobId: number) => jobId % 10 === 0;
+
+const jobToColor = (jobId: number) => {
+ if (jobId === 0) {
+ return COLORS.department.captain;
+ }
+ if (jobId >= 10 && jobId < 20) {
+ return COLORS.department.security;
+ }
+ if (jobId >= 20 && jobId < 30) {
+ return COLORS.department.medbay;
+ }
+ if (jobId >= 30 && jobId < 40) {
+ return COLORS.department.science;
+ }
+ if (jobId >= 40 && jobId < 50) {
+ return COLORS.department.engineering;
+ }
+ if (jobId >= 50 && jobId < 60) {
+ return COLORS.department.cargo;
+ }
+ if (jobId >= 60 && jobId < 200) {
+ return COLORS.department.service;
+ }
+ if (jobId >= 200 && jobId < 230) {
+ return COLORS.department.centcom;
+ }
+ return COLORS.department.other;
+};
+
+const statToIcon = (life_status: number) => {
+ switch (life_status) {
+ case STAT_LIVING:
+ return 'heart';
+ case STAT_DEAD:
+ return 'skull';
+ }
+ return 'heartbeat';
+};
+
+const healthSort = (a: CrewSensor, b: CrewSensor) => {
+ if (a.life_status > b.life_status) return -1;
+ if (a.life_status < b.life_status) return 1;
+ if (a.health < b.health) return -1;
+ if (a.health > b.health) return 1;
+ return 0;
+};
+
+const areaSort = (a: CrewSensor, b: CrewSensor) => {
+ a.area ??= '~';
+ b.area ??= '~';
+ if (a.area < b.area) return -1;
+ if (a.area > b.area) return 1;
+ return 0;
+};
+
+const healthToAttribute = (oxy: number, tox: number, burn: number, brute: number, attributeList: string[]) => {
+ const healthSum = oxy + tox + burn + brute;
+ const level = Math.min(Math.max(Math.ceil(healthSum / 25), 0), 5);
+ return attributeList[level];
+};
+
+type HealthStatProps = {
+ type: string;
+ value: number;
+};
+
+const HealthStat = (props: HealthStatProps) => {
+ const { type, value } = props;
+ return (
+
+ {value}
+
+ );
+};
+
+export const CrewConsole = () => {
+ return (
+
+
+
+
+
+ );
+};
+
+type CrewSensor = {
+ name: string;
+ assignment: string | undefined;
+ ijob: number;
+ life_status: number;
+ oxydam: number;
+ toxdam: number;
+ burndam: number;
+ brutedam: number;
+ area: string | undefined;
+ health: number;
+ can_track: BooleanLike;
+ ref: string;
+};
+
+type CrewConsoleData = {
+ sensors: CrewSensor[];
+ link_allowed: BooleanLike;
+};
+
+const CrewTable = (props, context) => {
+ const { data } = useBackend(context);
+ const { sensors } = data;
+
+ const [sortAsc, setSortAsc] = useLocalState(context, 'sortAsc', true);
+ const [searchQuery, setSearchQuery] = useLocalState(context, 'searchQuery', '');
+ const [sortBy, setSortBy] = useLocalState(context, 'sortBy', SORT_OPTIONS[0]);
+
+ const cycleSortBy = () => {
+ let idx = SORT_OPTIONS.indexOf(sortBy) + 1;
+ if (idx === SORT_OPTIONS.length) idx = 0;
+ setSortBy(SORT_OPTIONS[idx]);
+ };
+
+ const nameSearch = createSearch(searchQuery, (crew: CrewSensor) => crew.name);
+
+ const sorted = sensors.filter(nameSearch).sort((a, b) => {
+ switch (sortBy) {
+ case 'name':
+ return sortAsc ? +(a.name > b.name) : +(b.name > a.name);
+ case 'ijob':
+ return sortAsc ? a.ijob - b.ijob : b.ijob - a.ijob;
+ case 'health':
+ return sortAsc ? healthSort(a, b) : healthSort(b, a);
+ case 'area':
+ return sortAsc ? areaSort(a, b) : areaSort(b, a);
+ default:
+ return 0;
+ }
+ });
+
+ return (
+
+ );
+};
+
+type CrewTableEntryProps = {
+ sensor_data: CrewSensor;
+};
+
+const CrewTableEntry = (props: CrewTableEntryProps, context) => {
+ const { act, data } = useBackend(context);
+ const { link_allowed } = data;
+ const { sensor_data } = props;
+ const { name, assignment, ijob, life_status, oxydam, toxdam, burndam, brutedam, area, can_track } = sensor_data;
+
+ return (
+
+
+ {name}
+ {assignment !== undefined ? ` (${assignment})` : ''}
+
+
+ {oxydam !== undefined ? (
+
+ ) : life_status !== STAT_DEAD ? (
+
+ ) : (
+
+ )}
+
+
+ {oxydam !== undefined ? (
+
+
+ {'/'}
+
+ {'/'}
+
+ {'/'}
+
+
+ ) : life_status !== STAT_DEAD ? (
+ 'Alive'
+ ) : (
+ 'Dead'
+ )}
+
+ {area !== '~' && area !== undefined ? area : }
+ {!!link_allowed && (
+
+
+
+ )}
+
+ );
+};
From 0e40c0d41a1ce3b32905e2e09fd0b5fa18186ba4 Mon Sep 17 00:00:00 2001
From: XeonMations <62395746+XeonMations@users.noreply.github.com>
Date: Wed, 11 Sep 2024 10:22:22 +0300
Subject: [PATCH 2/9] [Port] Reworks universal recorder to be less bad (#11381)
* rahhhhh
* aaaaaa
* forgot a thing
* rahhhh
* grayscale
* mapload
* hope this works
---
code/__DEFINES/say.dm | 1 +
code/datums/looping_sounds/item_sounds.dm | 5 +
.../objects/items/devices/taperecorder.dm | 353 +++++++++++++-----
icons/obj/device.dmi | Bin 69874 -> 71024 bytes
icons/obj/radial_tape.dmi | Bin 0 -> 620 bytes
icons/obj/radial_taperecorder.dmi | Bin 0 -> 457 bytes
interface/stylesheet.dm | 1 +
sound/items/taperecorder/tape_flip.ogg | Bin 0 -> 27500 bytes
.../items/taperecorder/taperecorder_close.ogg | Bin 0 -> 35144 bytes
.../taperecorder/taperecorder_hiss_mid.ogg | Bin 0 -> 12177 bytes
.../taperecorder/taperecorder_hiss_start.ogg | Bin 0 -> 12159 bytes
.../items/taperecorder/taperecorder_open.ogg | Bin 0 -> 33754 bytes
.../items/taperecorder/taperecorder_play.ogg | Bin 0 -> 11670 bytes
.../items/taperecorder/taperecorder_print.ogg | Bin 0 -> 49899 bytes
.../items/taperecorder/taperecorder_stop.ogg | Bin 0 -> 14779 bytes
.../tgui-panel/styles/goon/chat-dark.scss | 5 +
.../tgui-panel/styles/goon/chat-light.scss | 5 +
17 files changed, 281 insertions(+), 89 deletions(-)
create mode 100644 icons/obj/radial_tape.dmi
create mode 100644 icons/obj/radial_taperecorder.dmi
create mode 100644 sound/items/taperecorder/tape_flip.ogg
create mode 100644 sound/items/taperecorder/taperecorder_close.ogg
create mode 100644 sound/items/taperecorder/taperecorder_hiss_mid.ogg
create mode 100644 sound/items/taperecorder/taperecorder_hiss_start.ogg
create mode 100644 sound/items/taperecorder/taperecorder_open.ogg
create mode 100644 sound/items/taperecorder/taperecorder_play.ogg
create mode 100644 sound/items/taperecorder/taperecorder_print.ogg
create mode 100644 sound/items/taperecorder/taperecorder_stop.ogg
diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm
index 3a746e3639194..dbd4f1aefcf54 100644
--- a/code/__DEFINES/say.dm
+++ b/code/__DEFINES/say.dm
@@ -63,6 +63,7 @@
#define SPAN_MEGAPHONE "megaphone"
#define SPAN_CLOWN "clowntext"
#define SPAN_SINGING "singing"
+#define SPAN_TAPE_RECORDER "tape_recorder"
//bitflag #defines for return value of the radio() proc.
#define ITALICS (1<<0)
diff --git a/code/datums/looping_sounds/item_sounds.dm b/code/datums/looping_sounds/item_sounds.dm
index 5b02eef9c4ce6..181e1d5a12b70 100644
--- a/code/datums/looping_sounds/item_sounds.dm
+++ b/code/datums/looping_sounds/item_sounds.dm
@@ -51,3 +51,8 @@
mid_sounds = list('sound/items/weeoo1.ogg' = 1)
mid_length = 15
volume = 20
+
+/datum/looping_sound/tape_recorder_hiss
+ mid_sounds = list('sound/items/taperecorder/taperecorder_hiss_mid.ogg')
+ start_sound = list('sound/items/taperecorder/taperecorder_hiss_start.ogg')
+ volume = 10
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index ab5d8bad62876..98d6381ede1fb 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -11,53 +11,105 @@
slot_flags = ITEM_SLOT_BELT
custom_materials = list(/datum/material/iron=60, /datum/material/glass=30)
force = 2
- throwforce = 0
+ throwforce = 2
+ speech_span = SPAN_TAPE_RECORDER
drop_sound = 'sound/items/handling/taperecorder_drop.ogg'
pickup_sound = 'sound/items/handling/taperecorder_pickup.ogg'
- var/recording = 0
- var/playing = 0
+ var/recording = FALSE
+ var/playing = FALSE
var/playsleepseconds = 0
var/obj/item/tape/mytape
var/starting_tape_type = /obj/item/tape/random
- var/open_panel = 0
- var/canprint = 1
+ var/open_panel = FALSE
+ var/canprint = TRUE
+ var/list/icons_available = list()
+ var/radial_icon_file = 'icons/obj/radial_taperecorder.dmi'
+ ///Whether we've warned during this recording session that the tape is almost up.
+ var/time_warned = FALSE
+ ///Seconds under which to warn that the tape is almost up.
+ var/time_left_warning = 60 SECONDS
+ ///Sound loop that plays when recording or playing back.
+ var/datum/looping_sound/tape_recorder_hiss/soundloop
/obj/item/taperecorder/Initialize(mapload)
. = ..()
if(starting_tape_type)
mytape = new starting_tape_type(src)
+ soundloop = new(src, FALSE)
update_icon()
become_hearing_sensitive()
+/obj/item/taperecorder/proc/readout()
+ if(mytape)
+ if(playing)
+ return "PLAYING"
+ else
+ var/time = mytape.used_capacity / 10 //deciseconds / 10 = seconds
+ var/mins = round(time / 60)
+ var/secs = time - mins * 60
+ return "[mins]m [secs]s"
+ return "NO TAPE INSERTED"
+
+/obj/item/taperecorder/proc/update_available_icons()
+ icons_available = list()
+
+ if(!playing && !recording)
+ icons_available += list("Record" = image(radial_icon_file,"record"))
+ icons_available += list("Play" = image(radial_icon_file,"play"))
+ if(canprint && mytape?.storedinfo.len)
+ icons_available += list("Print Transcript" = image(radial_icon_file,"print"))
+ if(playing || recording)
+ icons_available += list("Stop" = image(radial_icon_file,"stop"))
+ if(mytape)
+ icons_available += list("Eject" = image(radial_icon_file,"eject"))
+
+/obj/item/taperecorder/proc/update_sound()
+ if(!playing && !recording)
+ soundloop.stop()
+ else
+ soundloop.start()
+
/obj/item/taperecorder/Destroy()
+ QDEL_NULL(soundloop)
QDEL_NULL(mytape)
return ..()
/obj/item/taperecorder/examine(mob/user)
. = ..()
- . += "The wire panel is [open_panel ? "opened" : "closed"]."
-
+ if(in_range(src, user) || isobserver(user))
+ . += "The wire panel is [open_panel ? "opened" : "closed"]. The display reads:"
+ . += "[readout()]"
/obj/item/taperecorder/attackby(obj/item/I, mob/user, params)
if(!mytape && istype(I, /obj/item/tape))
if(!user.transferItemToLoc(I,src))
return
mytape = I
- to_chat(user, "You insert [I] into [src].")
- update_icon()
+ balloon_alert(user, "inserted [mytape]")
+ playsound(src, 'sound/items/taperecorder/taperecorder_close.ogg', 50, FALSE)
+ update_appearance()
/obj/item/taperecorder/proc/eject(mob/user)
- if(mytape)
- to_chat(user, "You remove [mytape] from [src].")
- stop()
- user.put_in_hands(mytape)
- mytape = null
- update_icon()
+ if(!mytape)
+ balloon_alert(user, "no tape!")
+ return
+ if(playing)
+ balloon_alert(user, "stop the tape first!")
+ return
+ if(recording)
+ balloon_alert(user, "stop the recording first!")
+ return
+ playsound(src, 'sound/items/taperecorder/taperecorder_open.ogg', 50, FALSE)
+ balloon_alert(user, "ejected [mytape]")
+ stop()
+ user.put_in_hands(mytape)
+ mytape = null
+ update_icon()
/obj/item/taperecorder/fire_act(exposed_temperature, exposed_volume)
- mytape.ruin() //Fires destroy the tape
+ mytape.unspool() //Fires unspool the tape, which makes sense if you don't think about it
..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
@@ -82,8 +134,10 @@
set category = "Object"
if(!can_use(usr))
+ balloon_alert(usr, "can't use!")
return
if(!mytape)
+ balloon_alert(usr, "no tape!")
return
eject(usr)
@@ -107,37 +161,48 @@
. = ..()
if(mytape && recording)
mytape.timestamp += mytape.used_capacity
- mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [message]"
+ mytape.storedinfo += "\[[time2text(mytape.used_capacity,"mm:ss")]\] [message]"
/obj/item/taperecorder/verb/record()
set name = "Start Recording"
set category = "Object"
if(!can_use(usr))
+ balloon_alert(usr, "can't use!")
return
- if(!mytape || mytape.ruined)
+ if(!mytape || mytape.unspooled)
+ balloon_alert(usr, "no spooled tape!")
return
if(recording)
+ balloon_alert(usr, "stop recording first!")
return
if(playing)
+ balloon_alert(usr, "already playing!")
return
+ playsound(src, 'sound/items/taperecorder/taperecorder_play.ogg', 50, FALSE)
+
if(mytape.used_capacity < mytape.max_capacity)
- to_chat(usr, "Recording started.")
- recording = 1
+ recording = TRUE
+ balloon_alert(usr, "started recording")
+ update_sound()
update_icon()
- mytape.timestamp += mytape.used_capacity
- mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording started."
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
var/max = mytape.max_capacity
while(recording && used < max)
- mytape.used_capacity++
- used++
- sleep(10)
- recording = 0
- update_icon()
+ mytape.used_capacity += 1 SECONDS
+ used += 1 SECONDS
+ if(max - used < time_left_warning && !time_warned)
+ time_warned = TRUE
+ balloon_alert(usr, "[(max - used) / 10] second\s left")
+ sleep(1 SECONDS)
+ if(used >= max)
+ balloon_alert(usr, "tape full!")
+ sleep(1 SECONDS) //prevent balloon alerts layering over the top of each other
+ stop()
else
- to_chat(usr, "The tape is full.")
+ balloon_alert(usr, "tape full!")
+ playsound(src, 'sound/items/taperecorder/taperecorder_stop.ogg', 50, FALSE)
/obj/item/taperecorder/verb/stop()
@@ -145,70 +210,93 @@
set category = "Object"
if(!can_use(usr))
+ balloon_alert(usr, "can't use!")
return
if(recording)
- recording = 0
- mytape.timestamp += mytape.used_capacity
- mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording stopped."
- to_chat(usr, "Recording stopped.")
- return
+ playsound(src, 'sound/items/taperecorder/taperecorder_stop.ogg', 50, FALSE)
+ balloon_alert(usr, "stopped recording")
+ recording = FALSE
else if(playing)
- playing = 0
- var/turf/T = get_turf(src)
- T.visible_message("Tape Recorder: Playback stopped.")
+ playsound(src, 'sound/items/taperecorder/taperecorder_stop.ogg', 50, FALSE)
+ balloon_alert(usr, "stopped playing")
+ playing = FALSE
+ time_warned = FALSE
update_icon()
-
+ update_sound()
/obj/item/taperecorder/verb/play()
set name = "Play Tape"
set category = "Object"
if(!can_use(usr))
+ balloon_alert(usr, "can't use!")
return
- if(!mytape || mytape.ruined)
+ if(!mytape || mytape.unspooled)
+ balloon_alert(usr, "no spooled tape!")
return
if(recording)
+ balloon_alert(usr, "stop recording first!")
return
if(playing)
+ balloon_alert(usr, "already playing!")
+ return
+ if(mytape.storedinfo?.len <= 0)
+ balloon_alert(usr, "[mytape] is empty!")
return
- playing = 1
+ playing = TRUE
update_icon()
- to_chat(usr, "Playing started.")
+ update_sound()
+ balloon_alert(usr, "started playing")
+ playsound(src, 'sound/items/taperecorder/taperecorder_play.ogg', 50, FALSE)
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
var/max = mytape.max_capacity
- for(var/i = 1, used < max, sleep(10 * playsleepseconds))
+ for(var/i = 1, used <= max, sleep(playsleepseconds))
if(!mytape)
break
- if(playing == 0)
+ if(playing == FALSE)
break
if(mytape.storedinfo.len < i)
+ balloon_alert(usr, "recording ended")
+ sleep(1 SECONDS)
break
- say(mytape.storedinfo[i])
+ say("[mytape.storedinfo[i]]")
if(mytape.storedinfo.len < i + 1)
playsleepseconds = 1
- sleep(10)
- say("End of recording.")
+ sleep(1 SECONDS)
else
playsleepseconds = mytape.timestamp[i + 1] - mytape.timestamp[i]
- if(playsleepseconds > 14)
- sleep(10)
- say("Skipping [playsleepseconds] seconds of silence")
- playsleepseconds = 1
+ if(playsleepseconds > 14 SECONDS)
+ sleep(1 SECONDS)
+ say("Skipping [playsleepseconds/10] seconds of silence.")
+ playsleepseconds = 1 SECONDS
i++
- playing = 0
- update_icon()
+ stop()
/obj/item/taperecorder/attack_self(mob/user)
- if(!mytape || mytape.ruined)
+ if(!mytape)
+ balloon_alert(user, "it's empty!")
return
- if(recording)
- stop()
- else
- record()
+
+ update_available_icons()
+ if(icons_available)
+ var/selection = show_radial_menu(user, src, icons_available, radius = 38, require_near = TRUE, tooltips = TRUE)
+ if(!selection)
+ return
+ switch(selection)
+ if("Stop")
+ stop()
+ if("Record")
+ record()
+ if("Play")
+ play()
+ if("Print Transcript")
+ print_transcript()
+ if("Eject")
+ eject(user)
/obj/item/taperecorder/verb/print_transcript()
@@ -217,15 +305,22 @@
var/list/transcribed_info = mytape.storedinfo
if(!length(transcribed_info))
- return
- if(!mytape)
+ balloon_alert(usr, "tape is empty!")
return
if(!canprint)
- to_chat(usr, "The recorder can't print that fast!")
- return
- if(recording || playing)
+ balloon_alert(usr, "can't print that fast!")
return
if(!can_use(usr))
+ balloon_alert(usr, "can't use!")
+ return
+ if(!mytape || mytape.unspooled)
+ balloon_alert(usr, "no spooled tape!")
+ return
+ if(recording)
+ balloon_alert(usr, "stop recording first!")
+ return
+ if(playing)
+ balloon_alert(usr, "already playing!")
return
var/transcribed_text = "Transcript:
"
@@ -240,7 +335,7 @@
// Very unexpected. Better abort non-gracefully.
if(excerpt_length > MAX_PAPER_LENGTH)
- say("Error: Data corruption detected. Cannot print.")
+ balloon_alert(usr, "data corrupted, can't print!")
CRASH("Transcript entry has more than [MAX_PAPER_LENGTH] chars: [excerpt_length] chars")
// If we're going to overflow the paper's length, print the current transcribed text out first and reset to prevent us
@@ -259,7 +354,10 @@
transcript_paper.add_raw_text(transcribed_text)
transcript_paper.name = "[paper_name] page [page_count]"
transcript_paper.update_appearance()
- to_chat(usr, "Transcript printed, [page_count] pages.")
+ balloon_alert(usr, "transcript printed\n[page_count] page\s")
+ playsound(src, 'sound/items/taperecorder/taperecorder_print.ogg', 50, FALSE)
+
+ // Can't put the entire stack into their hands if there's multple pages, but hey we can at least put one page in.
usr.put_in_hands(transcript_paper)
canprint = FALSE
addtimer(VARSET_CALLBACK(src, canprint, TRUE), 30 SECONDS)
@@ -272,7 +370,7 @@
/obj/item/tape
name = "tape"
- desc = "A magnetic tape that can hold up to ten minutes of content."
+ desc = "A magnetic tape that can hold up to ten minutes of content on either side."
icon_state = "tape_white"
icon = 'icons/obj/device.dmi'
item_state = "analyzer"
@@ -282,46 +380,123 @@
custom_materials = list(/datum/material/iron=20, /datum/material/glass=5)
force = 1
throwforce = 0
- var/max_capacity = 600
- var/used_capacity = 0
+ obj_flags = UNIQUE_RENAME //my mixtape
+ drop_sound = 'sound/items/handling/tape_drop.ogg'
+ pickup_sound = 'sound/items/handling/tape_pickup.ogg'
+ ///Because we can't expect God to do all the work.
+ var/initial_icon_state
+ var/max_capacity = 10 MINUTES
+ var/used_capacity = 0 SECONDS
+ ///Numbered list of chat messages the recorder has heard with spans and prepended timestamps. Used for playback and transcription.
var/list/storedinfo = list()
+ ///Numbered list of seconds the messages in the previous list appear at on the tape. Used by playback to get the timing right.
var/list/timestamp = list()
- var/ruined = 0
+ var/used_capacity_otherside = 0 SECONDS //Separate my side
+ var/list/storedinfo_otherside = list()
+ var/list/timestamp_otherside = list()
+ var/unspooled = FALSE
+ var/list/icons_available = list()
+ var/radial_icon_file = 'icons/obj/radial_tape.dmi'
/obj/item/tape/fire_act(exposed_temperature, exposed_volume)
- ruin()
+ unspool()
..()
-/obj/item/tape/attack_self(mob/user)
- if(!ruined)
- to_chat(user, "You pull out all the tape!")
- ruin()
+/obj/item/tape/Initialize(mapload)
+ . = ..()
+ initial_icon_state = icon_state //random tapes will set this after choosing their icon
+ var/mycolor = random_short_color()
+ name += " ([mycolor])" //multiple tapes can get confusing fast
+ if(icon_state == "tape_greyscale")
+ add_atom_colour("#[mycolor]", FIXED_COLOUR_PRIORITY)
+ if(prob(50))
+ tapeflip()
+
+/obj/item/tape/proc/update_available_icons()
+ icons_available = list()
+ if(!unspooled)
+ icons_available += list("Unwind tape" = image(radial_icon_file,"tape_unwind"))
+ icons_available += list("Flip tape" = image(radial_icon_file,"tape_flip"))
+/obj/item/tape/attack_self(mob/user)
+ update_available_icons()
+ if(icons_available)
+ var/selection = show_radial_menu(user, src, icons_available, radius = 38, require_near = TRUE, tooltips = TRUE)
+ if(!selection)
+ return
+ switch(selection)
+ if("Flip tape")
+ if(loc != user)
+ return
+ tapeflip()
+ balloon_alert(user, "flipped tape")
+ playsound(src, 'sound/items/taperecorder/tape_flip.ogg', 70, FALSE)
+ if("Unwind tape")
+ if(loc != user)
+ return
+ unspool()
+ balloon_alert(user, "unspooled tape")
+
+/obj/item/tape/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
+ if(prob(50))
+ tapeflip()
+ . = ..()
-/obj/item/tape/proc/ruin()
- //Lets not add infinite amounts of overlays when our fireact is called
- //repeatedly
- if(!ruined)
+/obj/item/tape/proc/unspool()
+ //Let's not add infinite amounts of overlays when our fire_act is called repeatedly
+ if(!unspooled)
add_overlay("ribbonoverlay")
- ruined = 1
-
+ unspooled = TRUE
-/obj/item/tape/proc/fix()
+/obj/item/tape/proc/respool()
cut_overlay("ribbonoverlay")
- ruined = 0
-
-
-/obj/item/tape/attackby(obj/item/I, mob/user, params)
- if(ruined && I.tool_behaviour == TOOL_SCREWDRIVER || istype(I, /obj/item/pen))
- to_chat(user, "You start winding the tape back in...")
- if(I.use_tool(src, user, 120))
- to_chat(user, "You wound the tape back in.")
- fix()
+ unspooled = FALSE
+
+/obj/item/tape/proc/tapeflip()
+ //first we save a copy of our current side
+ var/list/storedinfo_currentside = storedinfo.Copy()
+ var/list/timestamp_currentside = timestamp.Copy()
+ var/used_capacity_currentside = used_capacity
+ //then we overwite our current side with our other side
+ storedinfo = storedinfo_otherside.Copy()
+ timestamp = timestamp_otherside.Copy()
+ used_capacity = used_capacity_otherside
+ //then we overwrite our other side with the saved side
+ storedinfo_otherside = storedinfo_currentside.Copy()
+ timestamp_otherside = timestamp_currentside.Copy()
+ used_capacity_otherside = used_capacity_currentside
+
+ if(icon_state == initial_icon_state)
+ icon_state = "[initial_icon_state]_reverse"
+ else if(icon_state == "[initial_icon_state]_reverse") //so flipping doesn't overwrite an unexpected icon_state (e.g. an admin's)
+ icon_state = initial_icon_state
+
+/obj/item/tape/attackby(obj/item/tool, mob/user, params)
+ if(unspooled && (istype(tool, /obj/item/pen)))
+ balloon_alert(user, "respooling tape...")
+ if(!tool.use_tool(src, user, 12 SECONDS))
+ balloon_alert(user, "respooling failed!")
+ return FALSE
+ balloon_alert(user, "tape respooled")
+ respool()
+
+/obj/item/tape/screwdriver_act(mob/living/user, obj/item/tool)
+ if(!unspooled)
+ return FALSE
+ balloon_alert(user, "respooling tape...")
+ if(!tool.use_tool(src, user, 12 SECONDS))
+ balloon_alert(user, "respooling failed!")
+ return FALSE
+ balloon_alert(user, "tape respooled")
+ respool()
//Random colour tapes
/obj/item/tape/random
icon_state = "random_tape"
/obj/item/tape/random/Initialize(mapload)
+ icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple", "tape_greyscale")]"
. = ..()
- icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"
+
+/obj/item/tape/dyed
+ icon_state = "tape_greyscale"
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index e6379f882ff311eae7e9c120282afb275b2c4e7a..d7467f636522b59eca04d175d80972f34ab2ad93 100644
GIT binary patch
delta 52312
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