Fixes newscaster channels having a random chance of breaking upon creation of a new channel, refactors how channels are tracked in the first place (#92371)

## About The Pull Request

So in a recent round I noticed the newscaster UI was acting kind of
funky, where two channels seemed to overlap and weirdly pick between the
two in unpredictable ways. Looking into it, it seemed that somehow the
channels had managed to get their unique IDs to overlap-
Oh.

5d3353e7af/code/game/machinery/newscaster/newscaster_data.dm (L109-L131)
I see.

...I think that code speaks for itself, in how this could've gone wrong.

Anyhow, in this pr we entirely ditch this system, and instead make it
use an incremental and thus guaranteed to be unique ID.
This fixes our issues.

While we're here, we also remove the unused `channel_IDs` list, and
replace it with the associative lists `network_channels_by_id` and
`network_channels_by_name`. This allows us to also stop iterating over
every network channel until we find the one with the right name or ID.
We also rename some confusing, wrong, or non-standard vars while we're
here.
This commit is contained in:
_0Steven
2025-08-12 23:22:35 +02:00
committed by nevimer
parent 410f85475f
commit 1718c70f2f
8 changed files with 152 additions and 159 deletions

View File

@@ -158,8 +158,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list())
var/json_file = file("[GLOB.log_directory]/newscaster.json")
var/list/file_data = list()
var/pos = 1
for(var/V in GLOB.news_network.network_channels)
var/datum/feed_channel/channel = V
for(var/datum/feed_channel/channel as anything in GLOB.news_network.network_channels)
if(!istype(channel))
stack_trace("Non-channel in newscaster channel list")
continue

View File

@@ -305,14 +305,8 @@
var/author_key = input["author_ckey"]
var/channel_name = input["message"]
var/found_channel = FALSE
for(var/datum/feed_channel/channel as anything in GLOB.news_network.network_channels)
if(channel.channel_name == channel_name)
found_channel = TRUE
break
// No channel with a matching name, abort
if (!found_channel)
var/datum/feed_channel/chosen_channel = GLOB.news_network.network_channels_by_name[channel_name]
if(isnull(chosen_channel)) // No channel with a matching name, abort
return
message_admins(span_adminnotice("Incoming cross-sector newscaster article by [author_key] in channel [channel_name]."))

View File

@@ -42,9 +42,9 @@ GLOBAL_LIST_EMPTY(request_list)
///Referece to the photo used in picture messages.
var/photo_file
///What is the channel ID of the parent channel?
var/parent_ID
var/parent_id
///What number message is this? IE: The first message sent in a round including automated messages is message 1.
var/message_ID
var/message_id
/datum/feed_message/proc/return_author(censor)
if(censor == -1)
@@ -99,37 +99,13 @@ GLOBAL_LIST_EMPTY(request_list)
var/author_censor
/// Is this an admin channel? Allows for actions to be taken by the admin only.
var/is_admin_channel = FALSE
/// Channel ID is a random number sequence similar to account ID number that allows for us to link messages to the proper channels through the UI backend.
var/channel_ID
/// Channel ID is a unique number sequence similar to account ID number that allows for us to link messages to the proper channels through the UI backend.
var/channel_id
/// Should this channel send cross-server messages?
var/cross_sector = FALSE
/// Is this a cross-sector channel? If so, this channel can only receive messages via topics
var/receiving_cross_sector = FALSE
/datum/feed_channel/New()
. = ..()
channel_ID = random_channel_id_setup()
/**
* This proc assigns each feed_channel a random integer, from 1-999 as a unique identifier.
* Using this value, the TGUI window has a unique identifier to attach to messages that can be used to reattach them
* to their parent channels back in dreammaker.
* Based on implementation, we're limiting ourselves to only 998 player made channels maximum. How we'd use all of them, I don't know.
*/
/datum/feed_channel/proc/random_channel_id_setup()
if(!GLOB.news_network)
return //Should only apply to channels made before setup is finished, use hardset_channel for these
if(!GLOB.news_network.channel_IDs)
GLOB.news_network.channel_IDs += rand(1,999)
return //This will almost always be the station announcements channel here.
var/channel_id
for(var/i in 1 to 10000)
channel_id = rand(1, 999)
if(!GLOB.news_network.channel_IDs["[channel_ID]"])
break
channel_ID = channel_id
return channel_ID
/datum/feed_channel/proc/return_author(censor)
if(censor == -1)
censor = author_censor
@@ -173,36 +149,47 @@ GLOBAL_LIST_EMPTY(request_list)
/datum/feed_network
/// All the feed channels that have been made on the feed network.
var/list/datum/feed_channel/network_channels = list()
/// Associative list of all the feed channels that have been made on the feed network, from channel ID to channel.
var/list/datum/feed_channel/network_channels_by_id = list()
/// Associative list of all the feed channels that have been made on the feed network, from channel name to channel.
var/list/datum/feed_channel/network_channels_by_name = list()
/// What is the wanted issue being sent out to all newscasters.
var/datum/wanted_message/wanted_issue
/// What time was the last action taken on the feed_network?
var/last_action
/// What does this feed network say when a message/author is redacted?
var/redacted_text = "\[REDACTED\]"
/// List of all the network_channels Channel Id numbers, kept in a global easy to find place.
var/list/channel_IDs = list()
/// Channel ID to use when next making a new channel, to maintain unique IDs.
var/next_channel_id = 1
/// How many messages currently exist on this feed_network? Increments as new messages are written.
var/message_count = 0
/datum/feed_network/New()
create_feed_channel(NEWSCASTER_STATION_ANNOUNCEMENTS, "SS13", "Company news, staff announcements, and all the latest information. Have a secure shift!", locked = TRUE, hardset_channel = 1000)
create_feed_channel(NEWSCASTER_SPACE_BETTING, "NtOS", "News from the SpaceBet PDA App! Download now and make your own bets!", locked = TRUE, hardset_channel = 1001)
create_feed_channel(NEWSCASTER_STATION_ANNOUNCEMENTS, "SS13", "Company news, staff announcements, and all the latest information. Have a secure shift!", locked = TRUE)
create_feed_channel(NEWSCASTER_SPACE_BETTING, "NtOS", "News from the SpaceBet PDA App! Download now and make your own bets!", locked = TRUE)
wanted_issue = new /datum/wanted_message
/datum/feed_network/proc/create_feed_channel(channel_name, author, desc, locked, adminChannel = FALSE, hardset_channel = null, author_ckey = null, cross_sector = FALSE, cross_sector_delay = null, receiving_cross_sector = FALSE)
var/datum/feed_channel/newChannel = new /datum/feed_channel
newChannel.channel_name = channel_name
newChannel.author = author
newChannel.channel_desc = desc
newChannel.locked = locked
newChannel.is_admin_channel = adminChannel
newChannel.receiving_cross_sector = receiving_cross_sector
if(hardset_channel)
newChannel.channel_ID = hardset_channel
network_channels += newChannel
/datum/feed_network/proc/add_feed_channel(datum/feed_channel/new_channel)
network_channels += new_channel
network_channels_by_id["[new_channel.channel_id]"] = new_channel
network_channels_by_name["[new_channel.channel_name]"] = new_channel
/datum/feed_network/proc/create_feed_channel(channel_name, author, desc, locked, adminChannel = FALSE, author_ckey = null, cross_sector = FALSE, cross_sector_delay = null, receiving_cross_sector = FALSE)
var/datum/feed_channel/new_channel = new /datum/feed_channel
new_channel.channel_name = channel_name
new_channel.author = author
new_channel.channel_desc = desc
new_channel.locked = locked
new_channel.is_admin_channel = adminChannel
new_channel.receiving_cross_sector = receiving_cross_sector
new_channel.channel_id = next_channel_id
next_channel_id++
add_feed_channel(new_channel)
if(!cross_sector)
return
newChannel.cross_sector = TRUE
new_channel.cross_sector = TRUE
var/list/payload = list(
"author" = author,
"author_ckey" = author_ckey,
@@ -212,31 +199,32 @@ GLOBAL_LIST_EMPTY(request_list)
send2otherserver(html_decode(station_name()), channel_name, "create_news_channel", additional_data = payload)
/datum/feed_network/proc/submit_article(msg, author, channel_name, datum/picture/picture, adminMessage = FALSE, allow_comments = TRUE, update_alert = TRUE, mob/author_mob = null)
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = author
newMsg.body = msg
newMsg.time_stamp = "[station_time_timestamp()]"
newMsg.is_admin_message = adminMessage
newMsg.locked = !allow_comments
var/datum/feed_channel/chosen_channel = network_channels_by_name[channel_name]
if(isnull(chosen_channel))
stack_trace("Article submitted to non-existent newscaster channel: [channel_name]")
return
var/datum/feed_message/new_article = new /datum/feed_message
new_article.author = author
new_article.body = msg
new_article.time_stamp = "[station_time_timestamp()]"
new_article.is_admin_message = adminMessage
new_article.locked = !allow_comments
message_count++
last_action++
newMsg.creation_time = last_action
newMsg.message_ID = message_count
new_article.creation_time = last_action
new_article.message_id = message_count
if(picture)
newMsg.img = picture.picture_image
newMsg.caption = picture.caption
newMsg.photo_file = save_photo(picture.picture_image)
new_article.img = picture.picture_image
new_article.caption = picture.caption
new_article.photo_file = save_photo(picture.picture_image)
for(var/datum/feed_channel/channel in network_channels)
if(channel.channel_name != channel_name)
continue
chosen_channel.messages += new_article
new_article.parent_id = chosen_channel.channel_id
channel.messages += newMsg
newMsg.parent_ID = channel.channel_ID
if (!channel.cross_sector)
break
if(chosen_channel.cross_sector)
// Newscaster articles could be huge, and usefulness of first 50 symbols is dubious
message_admins(span_adminnotice("Outgoing cross-sector newscaster article by [key_name(author_mob) || author] in channel [channel_name]."))
var/list/payload = list(
@@ -245,11 +233,10 @@ GLOBAL_LIST_EMPTY(request_list)
"msg" = msg,
)
send2otherserver(html_decode(station_name()), channel_name, "create_news_article", additional_data = payload)
break
for(var/obj/machinery/newscaster/caster in GLOB.allCasters)
caster.news_alert(channel_name, update_alert)
return newMsg
return new_article
///Submits a comment on the news network
/datum/feed_network/proc/submit_comment(mob/user, comment_text, newscaster_username, datum/feed_message/current_message)

View File

@@ -196,11 +196,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
//Then, breaks down the messages that have been made on those channels.
if(current_channel)
for(var/datum/feed_message/feed_message as anything in current_channel.messages)
var/photo_ID = null
var/photo_id = null
var/list/comment_list
if(feed_message.img)
user << browse_rsc(feed_message.img, "tmp_photo[feed_message.message_ID].png")
photo_ID = "tmp_photo[feed_message.message_ID].png"
user << browse_rsc(feed_message.img, "tmp_photo[feed_message.message_id].png")
photo_id = "tmp_photo[feed_message.message_id].png"
for(var/datum/feed_comment/comment_message as anything in feed_message.comments)
comment_list += list(list(
"auth" = comment_message.author,
@@ -211,16 +211,16 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
"auth" = feed_message.author,
"body" = feed_message.body,
"time" = feed_message.time_stamp,
"channel_num" = feed_message.parent_ID,
"channel_num" = feed_message.parent_id,
"censored_message" = feed_message.body_censor,
"censored_author" = feed_message.author_censor,
"ID" = feed_message.message_ID,
"photo" = photo_ID,
"ID" = feed_message.message_id,
"photo" = photo_id,
"comments" = comment_list
))
data["viewing_channel"] = current_channel?.channel_ID
data["viewing_channel"] = current_channel?.channel_id
data["paper"] = paper_remaining
//Here we display all the information about the current channel.
data["channelName"] = current_channel?.channel_name
@@ -264,7 +264,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
"author" = channel.author,
"censored" = channel.censored,
"locked" = channel.locked,
"ID" = channel.channel_ID,
"ID" = channel.channel_id,
))
data["channels"] = channel_list
@@ -293,19 +293,20 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
switch(action)
if("setChannel")
var/prototype_channel = params["channel"]
if(isnull(prototype_channel))
var/selected_channel_id = params["channel"]
if(isnull(selected_channel_id))
return TRUE
for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels)
if(prototype_channel == potential_channel.channel_ID)
current_channel = potential_channel
var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[selected_channel_id]"]
if(isnull(potential_channel))
return TRUE
current_channel = potential_channel
if("createStory")
if(!current_channel)
balloon_alert(user, "select a channel first!")
return TRUE
var/prototype_channel = params["current"]
create_story(user, channel_name = prototype_channel)
var/current_channel_id = params["current"]
create_story(user, channel_id = current_channel_id)
if("togglePhoto")
toggle_photo(user)
@@ -352,7 +353,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
return TRUE
var/questionable_message = params["messageID"]
for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages)
if(iterated_feed_message.message_ID == questionable_message)
if(iterated_feed_message.message_id == questionable_message)
iterated_feed_message.toggle_censor_body()
break
@@ -366,7 +367,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
return TRUE
var/questionable_message = params["messageID"]
for(var/datum/feed_message/iterated_feed_message in current_channel.messages)
if(iterated_feed_message.message_ID == questionable_message)
if(iterated_feed_message.message_id == questionable_message)
iterated_feed_message.toggle_censor_author()
break
@@ -378,11 +379,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
if(!(admin_access in id_card?.GetAccess()))
say("Clearance not found.")
return TRUE
var/prototype_channel = (params["channel"])
for(var/datum/feed_channel/potential_channel in GLOB.news_network.network_channels)
if(prototype_channel == potential_channel.channel_ID)
current_channel = potential_channel
break
var/selected_channel_id = (params["channel"])
if(isnull(selected_channel_id))
return TRUE
var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[selected_channel_id]"]
if(isnull(potential_channel))
return TRUE
current_channel = potential_channel
current_channel.toggle_censor_D_class()
if("startComment")
@@ -394,7 +397,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
if(!commentable_message)
return TRUE
for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages)
if(iterated_feed_message.message_ID == commentable_message)
if(iterated_feed_message.message_id == commentable_message)
current_message = iterated_feed_message
return TRUE
@@ -660,10 +663,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
if(isnull(channel_locked))
return TRUE
for(var/datum/feed_channel/iterated_feed_channel as anything in GLOB.news_network.network_channels)
if(iterated_feed_channel.channel_name == channel_name)
tgui_alert(user, "ERROR: Feed channel with that name already exists on the Network.", list("Okay"))
return TRUE
var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_name[channel_name]
if(potential_channel)
tgui_alert(user, "ERROR: Feed channel with that name already exists on the Network.", list("Okay"))
return TRUE
var/list/hard_filter_result = is_ic_filtered(channel_name)
if(hard_filter_result)
@@ -769,13 +772,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
* Verifies that the message is being written to a real feed_channel, then provides a text input for the feed story to be written into.
* Finally, it submits the message to the network, is logged globally, and clears all message-specific variables from the machine.
*/
/obj/machinery/newscaster/proc/create_story(mob/user, channel_name)
for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels)
if(channel_name == potential_channel.channel_ID)
current_channel = potential_channel
break
/obj/machinery/newscaster/proc/create_story(mob/user, channel_id)
var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[channel_id]"]
if(isnull(potential_channel))
return
current_channel = potential_channel
if (current_channel.receiving_cross_sector)
if(current_channel.receiving_cross_sector)
return
var/temp_message = tgui_input_text(user, "Write your Feed story", "Network Channel Handler", feed_channel_message, max_length = MAX_BROADCAST_LEN, multiline = TRUE)

View File

@@ -268,10 +268,10 @@
var/has_image = FALSE
if(feed_messages.img)
has_image = TRUE
user << browse_rsc(feed_messages.img, "tmp_photo[feed_messages.message_ID].png")
user << browse_rsc(feed_messages.img, "tmp_photo[feed_messages.message_id].png")
channel_data["channel_messages"] += list(list(
"message" = "-[feed_messages.return_body(censored_check(feed_messages.body_censor_time))]",
"photo" = (has_image ? "tmp_photo[feed_messages.message_ID].png" : null),
"photo" = (has_image ? "tmp_photo[feed_messages.message_id].png" : null),
"author" = feed_messages.return_author(censored_check(feed_messages.author_censor_time)),
))
data["channel_data"] = list(channel_data)

View File

@@ -86,15 +86,15 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo
"author" = channel.author,
"censored" = channel.censored,
"locked" = channel.locked,
"ID" = channel.channel_ID,
"ID" = channel.channel_id,
))
if(current_channel)
for(var/datum/feed_message/feed_message as anything in current_channel.messages)
var/photo_ID = null
var/photo_id = null
var/list/comment_list
if(feed_message.img)
user << browse_rsc(feed_message.img, "tmp_photo[feed_message.message_ID].png")
photo_ID = "tmp_photo[feed_message.message_ID].png"
user << browse_rsc(feed_message.img, "tmp_photo[feed_message.message_id].png")
photo_id = "tmp_photo[feed_message.message_id].png"
for(var/datum/feed_comment/comment_message as anything in feed_message.comments)
comment_list += list(list(
"auth" = comment_message.author,
@@ -105,16 +105,16 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo
"auth" = feed_message.author,
"body" = feed_message.body,
"time" = feed_message.time_stamp,
"channel_num" = feed_message.parent_ID,
"channel_num" = feed_message.parent_id,
"censored_message" = feed_message.body_censor,
"censored_author" = feed_message.author_censor,
"ID" = feed_message.message_ID,
"photo" = photo_ID,
"ID" = feed_message.message_id,
"photo" = photo_id,
"comments" = comment_list
))
data["viewing_channel"] = current_channel?.channel_ID
data["viewing_channel"] = current_channel?.channel_id
//Here we display all the information about the current channel.
data["channelName"] = current_channel?.channel_name
data["channelAuthor"] = current_channel?.author
@@ -141,19 +141,20 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo
switch(action)
if("setChannel")
var/prototype_channel = params["channel"]
if(isnull(prototype_channel))
var/selected_channel_id = params["channel"]
if(isnull(selected_channel_id))
return TRUE
for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels)
if(prototype_channel == potential_channel.channel_ID)
current_channel = potential_channel
var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[selected_channel_id]"]
if(isnull(potential_channel))
return TRUE
current_channel = potential_channel
if("createStory")
if(!current_channel)
to_chat(usr, "select a channel first!")
return TRUE
var/prototype_channel = params["current"]
create_story(channel_name = prototype_channel)
var/current_channel_id = params["current"]
create_story(channel_id = current_channel_id)
if("togglePhoto")
toggle_photo()
@@ -189,23 +190,25 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo
if("storyCensor")
var/questionable_message = params["messageID"]
for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages)
if(iterated_feed_message.message_ID == questionable_message)
if(iterated_feed_message.message_id == questionable_message)
iterated_feed_message.toggle_censor_body()
break
if("author_censor")
var/questionable_message = params["messageID"]
for(var/datum/feed_message/iterated_feed_message in current_channel.messages)
if(iterated_feed_message.message_ID == questionable_message)
if(iterated_feed_message.message_id == questionable_message)
iterated_feed_message.toggle_censor_author()
break
if("channelDNotice")
var/prototype_channel = (params["channel"])
for(var/datum/feed_channel/potential_channel in GLOB.news_network.network_channels)
if(prototype_channel == potential_channel.channel_ID)
current_channel = potential_channel
break
var/selected_channel_id = (params["channel"])
if(isnull(selected_channel_id))
return TRUE
var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[selected_channel_id]"]
if(isnull(potential_channel))
return TRUE
current_channel = potential_channel
current_channel.toggle_censor_D_class()
if("startComment")
@@ -214,7 +217,7 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo
if(!commentable_message)
return TRUE
for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages)
if(iterated_feed_message.message_ID == commentable_message)
if(iterated_feed_message.message_id == commentable_message)
current_message = iterated_feed_message
return TRUE
@@ -284,10 +287,10 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo
/datum/newspanel/proc/create_channel(channel_locked)
if(!channel_name)
return
for(var/datum/feed_channel/iterated_feed_channel as anything in GLOB.news_network.network_channels)
if(iterated_feed_channel.channel_name == channel_name)
tgui_alert(usr, "ERROR: Feed channel with that name already exists on the Network.", list("Okay"))
return TRUE
var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_name[channel_name]
if(potential_channel)
tgui_alert(usr, "ERROR: Feed channel with that name already exists on the Network.", list("Okay"))
return TRUE
if(!channel_desc)
return TRUE
if(isnull(channel_locked))
@@ -334,11 +337,12 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo
* Verifies that the message is being written to a real feed_channel, then provides a text input for the feed story to be written into.
* Finally, it submits the message to the network, is logged globally, and clears all message-specific variables from the machine.
*/
/datum/newspanel/proc/create_story(channel_name)
for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels)
if(channel_name == potential_channel.channel_ID)
current_channel = potential_channel
break
/datum/newspanel/proc/create_story(channel_id)
var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[channel_id]"]
if(isnull(potential_channel))
return
current_channel = potential_channel
var/temp_message = tgui_input_text(usr, "Write your Feed story", "Network Channel Handler", feed_channel_message, max_length = MAX_BROADCAST_LEN, multiline = TRUE)
if(length(temp_message) <= 1)
return TRUE

View File

@@ -507,12 +507,8 @@ GLOBAL_VAR_INIT(library_table_modified, 0)
return
if(!GLOB.news_network)
say("No news network found on station. Aborting.")
var/channelexists = FALSE
for(var/datum/feed_channel/feed in GLOB.news_network.network_channels)
if(feed.channel_name == LIBRARY_NEWSFEED)
channelexists = TRUE
break
if(!channelexists)
var/datum/feed_channel/library_channel = GLOB.news_network.network_channels_by_name[LIBRARY_NEWSFEED]
if(isnull(library_channel))
GLOB.news_network.create_feed_channel(LIBRARY_NEWSFEED, "Library", "The official station book club!", null)
var/obj/machinery/libraryscanner/scan = get_scanner()

View File

@@ -170,19 +170,32 @@ GLOBAL_LIST_EMPTY_TYPED(active_bets, /datum/active_bet)
for(var/option in options)
if(!length(options[option]))
options[option] = list()
//we'll only advertise it on the first bet of the round, as to not make this overly annoying.
var/should_alert = FALSE
for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == NEWSCASTER_SPACE_BETTING)
if(!length(FC.messages))
should_alert = TRUE
newscaster_message = GLOB.news_network.submit_article("The bet [name] has started, place your bets now!", "NtOS Space Betting App", NEWSCASTER_SPACE_BETTING, null, update_alert = should_alert)
advertise_bet()
/datum/active_bet/Destroy(force)
GLOB.active_bets -= src
newscaster_message = null
return ..()
/// Place a feed article advertising our bet.
/datum/active_bet/proc/advertise_bet()
var/datum/feed_channel/betting_channel = GLOB.news_network.network_channels_by_name[NEWSCASTER_SPACE_BETTING]
if(isnull(betting_channel))
return
// We'll only advertise it on the first bet of the round, as to not make this overly annoying.
var/should_alert = !length(betting_channel.messages)
newscaster_message = GLOB.news_network.submit_article("The bet [name] has started, place your bets now!", "NtOS Space Betting App", NEWSCASTER_SPACE_BETTING, null, update_alert = should_alert)
/// Reply to our previously placed advertisement feed article.
/datum/active_bet/proc/reply_to_feed(winning_option)
if(isnull(newscaster_message))
return
GLOB.news_network.submit_comment(
comment_text = "The bet [name] has ended, the winner was [winning_option]!",
newscaster_username = "NtOS Betting Results",
current_message = newscaster_message,
)
///Returns how many bets there is per option
/datum/active_bet/proc/get_bets(datum/bank_account/user_account)
var/list/bets_per_option = list()
@@ -206,11 +219,8 @@ GLOBAL_LIST_EMPTY_TYPED(active_bets, /datum/active_bet)
var/datum/bank_account/refunded_account = existing_bets[1]
refunded_account.adjust_money(text2num(existing_bets[2]), "Refund: [name] gamble cancelled.")
return
GLOB.news_network.submit_comment(
comment_text = "The bet [name] has ended, the winner was [winning_option]!",
newscaster_username = "NtOS Betting Results",
current_message = newscaster_message,
)
reply_to_feed(winning_option)
var/list/winners = options[winning_option]
if(!length(winners))
return