Files
MrMelbert f3cc933465 You can purchase (lower quality) broadcast cameras as a cargo goodie (#95914)
## About The Pull Request

You can order a broadcast camera (the thing the curator can get which
lets them livestream to entertainment screens) in cargo for 800 credits

The cargo version has a smaller view range (4 tiles instead of 7 tiles)
and slows you down slightly

## Why It's Good For The Game

There's a lot of opportunities for gimmicks in being able to broadcast
to the station

Like if you're an antag and want to prove you have a hostage, or you
want to make rival news broadcasts, or you're a clown who livestreams
breaking into security, etc

Access to the ability to broadcast is very very limited (to a single
curator kit). If you wanna do any of the above you have to either play
curator and dedicate your entire round to it, ask the curator for
*their* gimmick item, or if there's no curator and you didn't roll it
you just can't do it at all. (And god forbid if someone steals the
camera or you lose it)

I think it's kinda sad so I wanted to add another way to obtain the
ability to broadcast and I figure cargo is a good place. It's lower
quality because I'm very wary of people robbing the curator of their
gimmick - The curator's camera is top of the line and that's what
differentiates it from the pleb's stuff.

## Changelog

🆑 Melbert
add: You can purchase (lower quality) broadcast cameras in cargo for
800cr
/🆑
2026-05-13 21:10:07 -04:00

145 lines
4.9 KiB
Plaintext

// 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
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)
/// Range of the camera
var/camera_range = 7
/// 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.view_range = camera_range
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/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/terminal_prompt_deny.ogg', vol = 20, vary = FALSE, ignore_walls = FALSE)
balloon_alert_to_viewers("offline")
/obj/item/broadcast_camera/click_alt(mob/user)
active_microphone = !active_microphone
/// Text popup for letting the user know that the microphone has changed state
balloon_alert(user, "microphone [active_microphone ? "" : "de"]activated")
///If the radio exists as an object, set its state accordingly
if(active)
set_microphone_state()
return CLICK_ACTION_SUCCESS
/obj/item/broadcast_camera/proc/set_microphone_state()
internal_radio.set_broadcasting(active_microphone)
// Orderable from cargo
/obj/item/broadcast_camera/cargo
slowdown = 0.3
item_flags = parent_type::item_flags | SLOWS_WHILE_IN_HAND
broadcast_name = "Camera Broadcast"
camera_range = 5
/obj/item/broadcast_camera/cargo/Initialize(mapload)
. = ..()
// Gives each cargo camera a unique network id
var/static/cargo_camera_network_id = 0
camera_networks = list("cargo_camera_id_[cargo_camera_network_id++]")