Skip to content

Commit

Permalink
Adds Curator news (#4723)
Browse files Browse the repository at this point in the history
* Adds broadcast cameras

* fix

* Update sound.dm
  • Loading branch information
JohnFulpWillard authored Jan 16, 2025
1 parent 76ae4eb commit d161fc6
Show file tree
Hide file tree
Showing 64 changed files with 469 additions and 19 deletions.
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

0 comments on commit d161fc6

Please sign in to comment.