Skip to content

Adds Curator news #4723

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions code/__DEFINES/cameranets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
/// Takes a position, transforms it into a chunk bounded position. Indexes at 1 so it'll land on actual turfs always
#define GET_CHUNK_COORD(v) (max((FLOOR(v, CHUNK_SIZE)), 1))

//List of different camera nets, cameras are given this in the map and camera consoles can only view them if
//they share this network with them.
#define CAMERANET_NETWORK_CURATOR "curator"
3 changes: 3 additions & 0 deletions code/__DEFINES/flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define EMP_PROTECT_CONTENTS (1<<1)
#define EMP_PROTECT_WIRES (1<<2)

///Protects against all EMP types.
#define EMP_PROTECT_ALL (EMP_PROTECT_SELF | EMP_PROTECT_CONTENTS | EMP_PROTECT_WIRES)

//Mob mobility var flags
/// can move
#define MOBILITY_MOVE (1<<0)
Expand Down
4 changes: 4 additions & 0 deletions code/__DEFINES/radio.dm
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
#define RADIO_KEY_AI_PRIVATE "o"
#define RADIO_TOKEN_AI_PRIVATE ":o"

#define RADIO_CHANNEL_ENTERTAINMENT "Entertainment"
#define RADIO_KEY_ENTERTAINMENT "p"
#define RADIO_TOKEN_ENTERTAINMENT ":p"

#define RADIO_CHANNEL_SYNDICATE "Syndicate"
#define RADIO_KEY_SYNDICATE "t"
Expand Down Expand Up @@ -78,6 +81,7 @@
#define FREQ_MEDICAL 1355 // Medical comms frequency, soft blue
#define FREQ_ENGINEERING 1357 // Engineering comms frequency, orange
#define FREQ_SECURITY 1359 // Security comms frequency, red
#define FREQ_ENTERTAINMENT 1415 // Used by entertainment monitors, cyan
#define FREQ_RADIO 1361 //monkestation edit
#define FREQ_UNCOMMON 1363 //monkestation addition, Light gray

Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/sound.dm
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,4 @@ GLOBAL_LIST_INIT(announcer_keys, list(
#define SFX_CRUNCHY_BUSH_WHACK "crunchy_bush_whack"
#define SFX_TREE_CHOP "tree_chop"
#define SFX_ROCK_TAP "rock_tap"
#define SFX_MUFFLED_SPEECH "muffspeech"
1 change: 1 addition & 0 deletions code/__DEFINES/span.dm
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define span_drone(str) ("<span class='drone'>" + str + "</span>")
#define span_engradio(str) ("<span class='engradio'>" + str + "</span>")
#define span_extremelybig(str) ("<span class='extremelybig'>" + str + "</span>")
#define span_enteradio(str) ("<span class='enteradio'>" + str + "</span>")
#define span_ghostalert(str) ("<span class='ghostalert'>" + str + "</span>")
#define span_green(str) ("<span class='green'>" + str + "</span>")
#define span_greenannounce(str) ("<span class='greenannounce'>" + str + "</span>")
Expand Down
2 changes: 2 additions & 0 deletions code/controllers/subsystem/blackbox.dm
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ SUBSYSTEM_DEF(blackbox)
record_feedback("tally", "radio_usage", 1, "centcom")
if(FREQ_AI_PRIVATE)
record_feedback("tally", "radio_usage", 1, "ai private")
if(FREQ_ENTERTAINMENT)
record_feedback("tally", "radio_usage", 1, "entertainment")
if(FREQ_CTF_RED)
record_feedback("tally", "radio_usage", 1, "CTF red team")
if(FREQ_CTF_BLUE)
Expand Down
2 changes: 2 additions & 0 deletions code/game/communications.dm
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ GLOBAL_LIST_INIT(radiochannels, list(
RADIO_CHANNEL_SUPPLY = FREQ_SUPPLY,
RADIO_CHANNEL_SERVICE = FREQ_SERVICE,
RADIO_CHANNEL_AI_PRIVATE = FREQ_AI_PRIVATE,
RADIO_CHANNEL_ENTERTAINMENT = FREQ_ENTERTAINMENT,
RADIO_CHANNEL_CTF_RED = FREQ_CTF_RED,
RADIO_CHANNEL_CTF_BLUE = FREQ_CTF_BLUE,
RADIO_CHANNEL_CTF_GREEN = FREQ_CTF_GREEN,
Expand All @@ -126,6 +127,7 @@ GLOBAL_LIST_INIT(reverseradiochannels, list(
"[FREQ_SUPPLY]" = RADIO_CHANNEL_SUPPLY,
"[FREQ_SERVICE]" = RADIO_CHANNEL_SERVICE,
"[FREQ_AI_PRIVATE]" = RADIO_CHANNEL_AI_PRIVATE,
"[FREQ_ENTERTAINMENT]" = RADIO_CHANNEL_ENTERTAINMENT,
"[FREQ_CTF_RED]" = RADIO_CHANNEL_CTF_RED,
"[FREQ_CTF_BLUE]" = RADIO_CHANNEL_CTF_BLUE,
"[FREQ_CTF_GREEN]" = RADIO_CHANNEL_CTF_GREEN,
Expand Down
57 changes: 55 additions & 2 deletions code/game/machinery/computer/telescreen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
frame_type = /obj/item/wallframe/telescreen/entertainment
var/icon_state_off = "entertainment_blank"
var/icon_state_on = "entertainment"
/// Virtual radio inside of the entertainment monitor to broadcast audio
var/obj/item/radio/entertainment/speakers/speakers

MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/security/telescreen/entertainment, 32)

Expand All @@ -56,6 +58,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/security/telescreen/entertai
/obj/machinery/computer/security/telescreen/entertainment/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_CLICK, PROC_REF(BigClick))
speakers = new(src)

/obj/machinery/computer/security/telescreen/entertainment/Destroy()
. = ..()
QDEL_NULL(speakers)

// Bypass clickchain to allow humans to use the telescreen from a distance
/obj/machinery/computer/security/telescreen/entertainment/proc/BigClick()
Expand Down Expand Up @@ -88,6 +95,53 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/security/telescreen/entertai

notify(network.len, announcement)

/**
* Adds a camera network to all entertainment monitors.
*
* * camera_net - The camera network ID to add to the monitors.
* * announcement - Optional, what announcement to make when the show starts.
*/
/proc/start_broadcasting_network(camera_net, announcement)
for(var/obj/machinery/computer/security/telescreen/entertainment/tv as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/computer/security/telescreen/entertainment))
tv.update_shows(
is_show_active = TRUE,
tv_show_id = camera_net,
announcement = announcement,
)

/**
* Removes a camera network from all entertainment monitors.
*
* * camera_net - The camera network ID to remove from the monitors.
* * announcement - Optional, what announcement to make when the show ends.
*/
/proc/stop_broadcasting_network(camera_net, announcement)
for(var/obj/machinery/computer/security/telescreen/entertainment/tv as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/computer/security/telescreen/entertainment))
tv.update_shows(
is_show_active = FALSE,
tv_show_id = camera_net,
announcement = announcement,
)

/**
* Sets the camera network status on all entertainment monitors.
* A way to force a network to a status if you are unsure of the current state.
*
* * camera_net - The camera network ID to set on the monitors.
* * is_show_active - Whether the show is active or not.
* * announcement - Optional, what announcement to make.
* Note this announcement will be made regardless of the current state of the show:
* This means if it's currently on and you set it to on, the announcement will still be made.
* Likewise, there's no way to differentiate off -> on and on -> off, unless you handle that yourself.
*/
/proc/set_network_broadcast_status(camera_net, is_show_active, announcement)
for(var/obj/machinery/computer/security/telescreen/entertainment/tv as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/computer/security/telescreen/entertainment))
tv.update_shows(
is_show_active = is_show_active,
tv_show_id = camera_net,
announcement = announcement,
)

/obj/machinery/computer/security/telescreen/rd
name = "\improper Research Director's telescreen"
desc = "Used for watching the AI and the RD's goons from the safety of his office."
Expand Down Expand Up @@ -271,5 +325,4 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/security/telescreen/entertai
is_show_active = !is_show_active
say("The [tv_show_name] show has [is_show_active ? "begun" : "ended"]")
var/announcement = is_show_active ? pick(tv_starters) : pick(tv_enders)
for(var/obj/machinery/computer/security/telescreen/entertainment/tv in GLOB.machines)
tv.update_shows(is_show_active, tv_network_id, announcement)
set_network_broadcast_status(tv_network_id, is_show_active, announcement)
4 changes: 2 additions & 2 deletions code/game/machinery/telecomms/machines/bus.dm
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@
/obj/machinery/telecomms/bus/preset_two
id = "Bus 2"
network = "tcommsat"
freq_listening = list(FREQ_SUPPLY, FREQ_SERVICE)
autolinkers = list("processor2", "supply", "service")
freq_listening = list(FREQ_SUPPLY, FREQ_SERVICE, FREQ_ENTERTAINMENT)
autolinkers = list("processor2", "supply", "service", "entertainment")

/obj/machinery/telecomms/bus/preset_three
id = "Bus 3"
Expand Down
26 changes: 23 additions & 3 deletions code/game/machinery/telecomms/machines/hub.dm
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,27 @@
/obj/machinery/telecomms/hub/preset
id = "Hub"
network = "tcommsat"
autolinkers = list("hub", "relay", "s_relay", "m_relay", "r_relay", "h_relay", "science", "medical",
"supply", "service", "common", "command", "engineering", "security",
"receiverA", "receiverB", "broadcasterA", "broadcasterB", "autorelay", "messaging")
autolinkers = list(
"hub",
"relay",
"s_relay",
"m_relay",
"r_relay",
"h_relay",
"science",
"medical",
"supply",
"service",
"common",
"command",
"engineering",
"entertainment",
"security",
"receiverA",
"receiverB",
"broadcasterA",
"broadcasterB",
"autorelay",
"messaging",
)

2 changes: 1 addition & 1 deletion code/game/machinery/telecomms/machines/receiver.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
id = "Receiver A"
network = "tcommsat"
autolinkers = list("receiverA") // link to relay
freq_listening = list(FREQ_SCIENCE, FREQ_MEDICAL, FREQ_SUPPLY, FREQ_SERVICE)
freq_listening = list(FREQ_SCIENCE, FREQ_MEDICAL, FREQ_SUPPLY, FREQ_SERVICE, FREQ_ENTERTAINMENT)


//--PRESET RIGHT--//
Expand Down
6 changes: 3 additions & 3 deletions code/game/machinery/telecomms/machines/server.dm
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@
autolinkers = list("supply")

/obj/machinery/telecomms/server/presets/service
id = "Service Server"
freq_listening = list(FREQ_SERVICE)
autolinkers = list("service")
id = "Service & Entertainment Server"
freq_listening = list(FREQ_SERVICE, FREQ_ENTERTAINMENT)
autolinkers = list("service", "entertainment")

/obj/machinery/telecomms/server/presets/common
id = "Common Server"
Expand Down
128 changes: 128 additions & 0 deletions code/game/objects/items/devices/broadcast_camera.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Unique broadcast camera given to the first Curator
// Only one should exist ideally, if other types are created they must have different camera_networks
// Broadcasts its surroundings to entertainment monitors and its audio to entertainment radio channel
/obj/item/broadcast_camera
name = "broadcast camera"
desc = "A large camera that streams its live feed and audio to entertainment monitors across the station, allowing everyone to watch the broadcast."
desc_controls = "Right-click to change the broadcast name. Alt-click to toggle microphone."
icon = 'icons/obj/service/broadcast.dmi'
icon_state = "broadcast_cam0"
base_icon_state = "broadcast_cam"
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
force = 8
throwforce = 12
w_class = WEIGHT_CLASS_NORMAL
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
slot_flags = NONE
light_system = OVERLAY_LIGHT
light_color = COLOR_SOFT_RED
// light_range = 1 //Monkestation removal
light_power = 0.3
light_on = FALSE
/// Is camera streaming
var/active = FALSE
/// Is the microphone turned on
var/active_microphone = TRUE
/// The name of the broadcast
var/broadcast_name = "Curator News"
/// The networks it broadcasts to, default is CAMERANET_NETWORK_CURATOR
var/list/camera_networks = list(CAMERANET_NETWORK_CURATOR)
/// The "virtual" security camera inside of the physical camera
var/obj/machinery/camera/internal_camera
/// The "virtual" radio inside of the the physical camera, a la microphone
var/obj/item/radio/entertainment/microphone/internal_radio

/obj/item/broadcast_camera/Initialize(mapload)
. = ..()

AddElement(/datum/element/empprotection, EMP_PROTECT_ALL)

/obj/item/broadcast_camera/Destroy(force)
QDEL_NULL(internal_radio)
QDEL_NULL(internal_camera)
return ..()

/obj/item/broadcast_camera/update_icon_state()
icon_state = "[base_icon_state][active]"
return ..()

/obj/item/broadcast_camera/attack_self(mob/user, modifiers)
. = ..()
active = !active
if(active)
on_activating()
else
on_deactivating()

/obj/item/broadcast_camera/attack_self_secondary(mob/user, modifiers)
. = ..()
broadcast_name = tgui_input_text(user = user, title = "Broadcast Name", message = "What will be the name of your broadcast?", default = "[broadcast_name]", max_length = MAX_CHARTER_LEN)

/obj/item/broadcast_camera/examine(mob/user)
. = ..()
. += span_notice("Broadcast name is <b>[broadcast_name]</b>")
. += span_notice("The microphone is <b>[active_microphone ? "On" : "Off"]</b>")

/obj/item/broadcast_camera/on_enter_storage(datum/storage/master_storage)
. = ..()
if(active)
on_deactivating()

/obj/item/broadcast_camera/dropped(mob/user, silent)
. = ..()
if(active)
on_deactivating()

/// When activating the camera
/obj/item/broadcast_camera/proc/on_activating()
if(!iscarbon(loc))
return
active = TRUE
update_icon_state()
/// The carbon who wielded the camera, allegedly
var/mob/living/carbon/wielding_carbon = loc

// INTERNAL CAMERA
internal_camera = new(wielding_carbon) // Cameras for some reason do not work inside of obj's
internal_camera.internal_light = FALSE
internal_camera.network = camera_networks
internal_camera.c_tag = "LIVE: [broadcast_name]"
start_broadcasting_network(camera_networks, "[broadcast_name] is now LIVE!")

// INTERNAL RADIO
internal_radio = new(src)
/// Sets the state of the microphone
set_microphone_state()

set_light_on(TRUE)
playsound(source = src, soundin = 'sound/machines/terminal_processing.ogg', vol = 20, vary = FALSE, ignore_walls = FALSE)
balloon_alert_to_viewers("live!")

/// When deactivating the camera
/obj/item/broadcast_camera/proc/on_deactivating()
active = FALSE
update_icon_state()
QDEL_NULL(internal_camera)
QDEL_NULL(internal_radio)

stop_broadcasting_network(camera_networks)

set_light_on(FALSE)
playsound(source = src, soundin = 'sound/machines/terminal_prompt_deny.ogg', vol = 20, vary = FALSE, ignore_walls = FALSE)
balloon_alert_to_viewers("offline")

/obj/item/broadcast_camera/AltClick(mob/user)
if(!user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH))
return
active_microphone = !active_microphone

/// Text popup for letting the user know that the microphone has changed state
balloon_alert(user, "turned [active_microphone ? "on" : "off"] the microphone.")

///If the radio exists as an object, set its state accordingly
if(active)
set_microphone_state()

/obj/item/broadcast_camera/proc/set_microphone_state()
internal_radio.set_broadcasting(active_microphone)
19 changes: 18 additions & 1 deletion code/game/objects/items/devices/radio/encryptionkey.dm
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@
greyscale_config = /datum/greyscale_config/encryptionkey_service
greyscale_colors = "#ebebeb#3bca5a"

/obj/item/encryptionkey/headset_srvent
name = "press radio encryption key"
icon_state = "cypherkey_service"
channels = list(RADIO_CHANNEL_SERVICE = 1, RADIO_CHANNEL_ENTERTAINMENT = 0)
greyscale_config = /datum/greyscale_config/encryptionkey_service
greyscale_colors = "#83eb8f#3bca5a"

/obj/item/encryptionkey/headset_com
name = "command radio encryption key"
icon_state = "cypherkey_cube"
Expand Down Expand Up @@ -188,7 +195,17 @@
greyscale_colors = "#24a157#dca01b"

/obj/item/encryptionkey/ai //ported from NT, this goes 'inside' the AI.
channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_SECURITY = 1, RADIO_CHANNEL_ENGINEERING = 1, RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_MEDICAL = 1, RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SERVICE = 1, RADIO_CHANNEL_AI_PRIVATE = 1)
channels = list(
RADIO_CHANNEL_COMMAND = 1,
RADIO_CHANNEL_SECURITY = 1,
RADIO_CHANNEL_ENGINEERING = 1,
RADIO_CHANNEL_SCIENCE = 1,
RADIO_CHANNEL_MEDICAL = 1,
RADIO_CHANNEL_SUPPLY = 1,
RADIO_CHANNEL_SERVICE = 1,
RADIO_CHANNEL_AI_PRIVATE = 1,
RADIO_CHANNEL_ENTERTAINMENT = 1,
)

/obj/item/encryptionkey/secbot
channels = list(RADIO_CHANNEL_AI_PRIVATE = 1, RADIO_CHANNEL_SECURITY = 1)
Expand Down
Loading
Loading