diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm
index 69d5a23bb2b..f0dc1c3c720 100644
--- a/code/_onclick/cyborg.dm
+++ b/code/_onclick/cyborg.dm
@@ -46,6 +46,10 @@
RestrainedClickOn(A)
return
*/
+ if(aicamera.in_camera_mode) //Cyborg picture taking
+ aicamera.camera_mode_off()
+ aicamera.captureimage(A, usr)
+ return
var/obj/item/W = get_active_hand()
diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm
index 3f0695d07ae..6be391c1312 100644
--- a/code/datums/wires/robot.dm
+++ b/code/datums/wires/robot.dm
@@ -59,6 +59,20 @@ var/const/BORG_WIRE_CAMERA = 16
if(new_ai && (new_ai != R.connected_ai))
R.connected_ai = new_ai
R.notify_ai(1)
+ var/numberer = 1 // Send images the Cyborg has taken to the AI's album upon sync.
+ for(var/datum/picture/z in R.aicamera.aipictures)
+ for(var/datum/picture/t in R.connected_ai.aicamera.aipictures) //Hopefully to prevent someone spamming images to silicons, by spamming this wire
+ if((z.fields["pixel_y"] != t.fields["pixel_y"]) && (z.fields["pixel_x"] != t.fields["pixel_x"])) //~2.26 out of 1000 chance this will stop something it shouldn't
+ var/datum/picture/p = new()
+ p = z
+ p.fields["name"] = "Uploaded Image [numberer] (synced from [R.name])"
+ R.connected_ai.aicamera.aipictures += p
+ else
+ continue
+ numberer++
+ if(R.aicamera.aipictures.len > 0)
+ R << "Locally saved images synced with AI. Images were retained in local database in case of loss of connection with the AI."
+
if (BORG_WIRE_CAMERA)
if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes)
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index afaca2f0e76..c9837d90924 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -1,1030 +1,1054 @@
-//##############################################
-//################### NEWSCASTERS BE HERE! ####
-//###-Agouri###################################
-
-/datum/feed_message
- var/author =""
- var/body =""
- //var/parent_channel
- var/backup_body =""
- var/backup_author =""
- var/is_admin_message = 0
- var/icon/img = null
- var/time_stamp = ""
-
-/datum/feed_channel
- var/channel_name=""
- var/list/datum/feed_message/messages = list()
- //var/message_count = 0
- var/locked=0
- var/author=""
- var/backup_author=""
- var/censored=0
- var/is_admin_channel=0
- //var/page = null //For newspapers
-
-/datum/feed_message/proc/clear()
- src.author = ""
- src.body = ""
- src.backup_body = ""
- src.backup_author = ""
- src.img = null
-
-/datum/feed_channel/proc/clear()
- src.channel_name = ""
- src.messages = list()
- src.locked = 0
- src.author = ""
- src.backup_author = ""
- src.censored = 0
- src.is_admin_channel = 0
-
-/datum/feed_network
- var/list/datum/feed_channel/network_channels = list()
- var/datum/feed_message/wanted_issue
-
-/datum/feed_network/New()
- CreateFeedChannel("Central Command", "Centcom Official", 1)
-
-/datum/feed_network/proc/CreateFeedChannel(var/channel_name, var/author, var/locked, var/adminChannel = 0)
- var/datum/feed_channel/newChannel = new /datum/feed_channel
- newChannel.channel_name = channel_name
- newChannel.author = author
- newChannel.locked = locked
- newChannel.is_admin_channel = adminChannel
- network_channels += newChannel
-
-/datum/feed_network/proc/SubmitArticle(var/msg, var/author, var/channel_name, var/obj/item/weapon/photo/photo, var/adminMessage = 0)
- var/datum/feed_message/newMsg = new /datum/feed_message
- newMsg.author = author
- newMsg.body = msg
- newMsg.time_stamp = "[worldtime2text()]"
- newMsg.is_admin_message = adminMessage
- if(photo)
- newMsg.img = photo.img
- for(var/datum/feed_channel/FC in network_channels)
- if(FC.channel_name == channel_name)
- FC.messages += newMsg //Adding message to the network's appropriate feed_channel
- break
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- NEWSCASTER.newsAlert(channel_name)
-
-
-var/datum/feed_network/news_network = new /datum/feed_network //The global news-network, which is coincidentally a global list.
-
-var/list/obj/machinery/newscaster/allCasters = list() //Global list that will contain reference to all newscasters in existence.
-
-
-/obj/item/newscaster_frame
- name = "newscaster frame"
- desc = "Used to build newscasters, just secure to the wall."
- icon_state = "newscaster"
- item_state = "syringe_kit"
- m_amt = 14000
- g_amt = 8000
-
-/obj/item/newscaster_frame/proc/try_build(turf/on_wall)
- if (get_dist(on_wall,usr)>1)
- return
- var/ndir = get_dir(usr,on_wall)
- if (!(ndir in cardinal))
- return
- var/turf/loc = get_turf(usr)
- var/area/A = loc.loc
- if (!istype(loc, /turf/simulated/floor))
- usr << "Newscaster cannot be placed on this spot."
- return
- if (A.requires_power == 0 || A.name == "Space")
- usr << "Newscaster cannot be placed in this area."
- return
- for(var/obj/machinery/newscaster/T in loc)
- usr << "There is another newscaster here."
- return
- var/obj/machinery/newscaster/N = new(loc)
- N.pixel_y -= (loc.y - on_wall.y) * 32
- N.pixel_x -= (loc.x - on_wall.x) * 32
- qdel(src)
-
-
-
-
-/obj/machinery/newscaster
- name = "newscaster"
- desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!"
- icon = 'icons/obj/terminals.dmi'
- icon_state = "newscaster_normal"
- var/isbroken = 0 //1 if someone banged it with something heavy
- var/ispowered = 1 //starts powered, changes with power_change()
- //var/list/datum/feed_channel/channel_list = list() //This list will contain the names of the feed channels. Each name will refer to a data region where the messages of the feed channels are stored.
- //OBSOLETE: We're now using a global news network
- var/screen = 0
- // 0 = welcome screen - main menu
- // 1 = view feed channels
- // 2 = create feed channel
- // 3 = create feed story
- // 4 = feed story submited sucessfully
- // 5 = feed channel created successfully
- // 6 = ERROR: Cannot create feed story
- // 7 = ERROR: Cannot create feed channel
- // 8 = print newspaper
- // 9 = viewing channel feeds
- // 10 = censor feed story
- // 11 = censor feed channel
- //Holy shit this is outdated, made this when I was still starting newscasters :3
- var/paper_remaining = 0
- var/securityCaster = 0
- // 0 = Caster cannot be used to issue wanted posters
- // 1 = the opposite
- var/unit_no = 0 //Each newscaster has a unit number
- //var/datum/feed_message/wanted //We're gonna use a feed_message to store data of the wanted person because fields are similar
- //var/wanted_issue = 0 //OBSOLETE
- // 0 = there's no WANTED issued, we don't need a special icon_state
- // 1 = Guess what.
- var/alert_delay = 500
- var/alert = 0
- // 0 = there hasn't been a news/wanted update in the last alert_delay
- // 1 = there has
- var/scanned_user = "Unknown" //Will contain the name of the person who currently uses the newscaster
- var/msg = ""; //Feed message
- var/obj/item/weapon/photo/photo = null
- var/channel_name = ""; //the feed channel which will be receiving the feed, or being created
- var/c_locked=0; //Will our new channel be locked to public submissions?
- var/hitstaken = 0 //Death at 3 hits from an item with force>=15
- var/datum/feed_channel/viewing_channel = null
- luminosity = 0
- anchored = 1
-
-
-/obj/machinery/newscaster/security_unit //Security unit
- name = "security newscaster"
- securityCaster = 1
-
-/obj/machinery/newscaster/New()
- allCasters += src
- src.paper_remaining = 15
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- src.unit_no++
- src.update_icon() //for any custom ones on the map...
- ..() //I just realised the newscasters weren't in the global machines list. The superconstructor call will tend to that
-
-/obj/machinery/newscaster/Destroy()
- allCasters -= src
- ..()
-
-/obj/machinery/newscaster/update_icon()
- if(!ispowered || isbroken)
- icon_state = "newscaster_off"
- if(isbroken) //If the thing is smashed, add crack overlay on top of the unpowered sprite.
- src.overlays.Cut()
- src.overlays += image(src.icon, "crack3")
- return
-
- src.overlays.Cut() //reset overlays
-
- if(news_network.wanted_issue) //wanted icon state, there can be no overlays on it as it's a priority message
- icon_state = "newscaster_wanted"
- return
-
- if(alert) //new message alert overlay
- src.overlays += "newscaster_alert"
-
- if(hitstaken > 0) //Cosmetic damage overlay
- src.overlays += image(src.icon, "crack[hitstaken]")
-
- icon_state = "newscaster_normal"
- return
-
-/obj/machinery/newscaster/power_change()
- if(isbroken) //Broken shit can't be powered.
- return
- if( src.powered() )
- src.ispowered = 1
- stat &= ~NOPOWER
- src.update_icon()
- else
- spawn(rand(0, 15))
- src.ispowered = 0
- stat |= NOPOWER
- src.update_icon()
-
-
-/obj/machinery/newscaster/ex_act(severity)
- switch(severity)
- if(1.0)
- qdel(src)
- return
- if(2.0)
- src.isbroken=1
- if(prob(50))
- qdel(src)
- else
- src.update_icon() //can't place it above the return and outside the if-else. or we might get runtimes of null.update_icon() if(prob(50)) goes in.
- return
- else
- if(prob(50))
- src.isbroken=1
- src.update_icon()
- return
- return
-
-/obj/machinery/newscaster/attack_ai(mob/user as mob)
- return src.attack_hand(user)
-
-/obj/machinery/newscaster/attack_hand(mob/user as mob) //########### THE MAIN BEEF IS HERE! And in the proc below this...############
- if(!src.ispowered || src.isbroken)
- return
- if(istype(user, /mob/living/carbon/human) || istype(user,/mob/living/silicon) )
- var/mob/living/human_or_robot_user = user
- var/dat
-
- src.scan_user(human_or_robot_user) //Newscaster scans you
-
- switch(screen)
- if(0)
- dat += "Welcome to Newscasting Unit #[src.unit_no].
Interface & News networks Operational."
- dat += "
Property of Nanotransen Inc"
- if(news_network.wanted_issue)
- dat+= "
Read Wanted Issue"
- dat+= "
Create Feed Channel"
- dat+= "
View Feed Channels"
- dat+= "
Submit new Feed story"
- dat+= "
Print newspaper"
- dat+= "
Re-scan User"
- dat+= "
Exit"
- if(src.securityCaster)
- var/wanted_already = 0
- if(news_network.wanted_issue)
- wanted_already = 1
-
- dat+="
Feed Security functions:
"
- dat+="
[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue"
- dat+="
Censor Feed Stories"
- dat+="
Mark Feed Channel with Nanotrasen D-Notice"
- dat+="
The newscaster recognises you as: [src.scanned_user]"
- if(1)
- dat+= "Station Feed Channels
"
- if( isemptylist(news_network.network_channels) )
- dat+="No active channels found..."
- else
- for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
- if(CHANNEL.is_admin_channel)
- dat+="[CHANNEL.channel_name]
"
- else
- dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
- /*for(var/datum/feed_channel/CHANNEL in src.channel_list)
- dat+="[CHANNEL.channel_name]:
\[created by: [CHANNEL.author]\]
"
- if( isemptylist(CHANNEL.messages) )
- dat+="No feed messages found in channel...
"
- else
- for(var/datum/feed_message/MESSAGE in CHANNEL.messages)
- dat+="-[MESSAGE.body]
\[Story by [MESSAGE.author]\]
"*/
-
- dat+="
Refresh"
- dat+="
Back"
- if(2)
- dat+="Creating new Feed Channel..."
- dat+="
Channel Name: [src.channel_name]
"
- dat+="Channel Author: [src.scanned_user]
"
- dat+="Will Accept Public Feeds: [(src.c_locked) ? ("NO") : ("YES")]
"
- dat+="
Submit
Cancel
"
- if(3)
- dat+="Creating new Feed Message..."
- dat+="
Receiving Channel: [src.channel_name]
" //MARK
- dat+="Message Author: [src.scanned_user]
"
- dat+="Message Body: [src.msg]
"
- dat+="Attach Photo: [(src.photo ? "Photo Attached" : "No Photo")]"
- dat+="
Submit
Cancel
"
- if(4)
- dat+="Feed story successfully submitted to [src.channel_name].
"
- dat+="
Return
"
- if(5)
- dat+="Feed Channel [src.channel_name] created successfully.
"
- dat+="
Return
"
- if(6)
- dat+="ERROR: Could not submit Feed story to Network.
"
- if(src.channel_name=="")
- dat+="•Invalid receiving channel name.
"
- if(src.scanned_user=="Unknown")
- dat+="•Channel author unverified.
"
- if(src.msg == "" || src.msg == "\[REDACTED\]")
- dat+="•Invalid message body.
"
-
- dat+="
Return
"
- if(7)
- dat+="ERROR: Could not submit Feed Channel to Network.
"
- //var/list/existing_channels = list() //Let's get dem existing channels - OBSOLETE
- var/list/existing_authors = list()
- for(var/datum/feed_channel/FC in news_network.network_channels)
- //existing_channels += FC.channel_name //OBSOLETE
- if(FC.author == "\[REDACTED\]")
- existing_authors += FC.backup_author
- else
- existing_authors += FC.author
- if(src.scanned_user in existing_authors)
- dat+="•There already exists a Feed channel under your name.
"
- if(src.channel_name=="" || src.channel_name == "\[REDACTED\]")
- dat+="•Invalid channel name.
"
- var/check = 0
- for(var/datum/feed_channel/FC in news_network.network_channels)
- if(FC.channel_name == src.channel_name)
- check = 1
- break
- if(check)
- dat+="•Channel name already in use.
"
- if(src.scanned_user=="Unknown")
- dat+="•Channel author unverified.
"
- dat+="
Return
"
- if(8)
- var/total_num=length(news_network.network_channels)
- var/active_num=total_num
- var/message_num=0
- for(var/datum/feed_channel/FC in news_network.network_channels)
- if(!FC.censored)
- message_num += length(FC.messages) //Dont forget, datum/feed_channel's var messages is a list of datum/feed_message
- else
- active_num--
- dat+="Network currently serves a total of [total_num] Feed channels, [active_num] of which are active, and a total of [message_num] Feed Stories." //TODO: CONTINUE
- dat+="
Liquid Paper remaining: [(src.paper_remaining) *100 ] cm^3"
- dat+="
Print Paper"
- dat+="
Cancel"
- if(9)
- dat+="[src.viewing_channel.channel_name]: \[created by: [src.viewing_channel.author]\]
"
- if(src.viewing_channel.censored)
- dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
- dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
- else
- if( isemptylist(src.viewing_channel.messages) )
- dat+="No feed messages found in channel...
"
- else
- var/i = 0
- for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages)
- i++
- dat+="-[MESSAGE.body]
"
- if(MESSAGE.img)
- usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
- dat+="
"
- dat+="\[Story by [MESSAGE.author] \] - ([MESSAGE.time_stamp])
"
- dat+="
Refresh"
- dat+="
Back"
- if(10)
- dat+="Nanotrasen Feed Censorship Tool
"
- dat+="NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.
"
- dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it."
- dat+="
Select Feed channel to get Stories from:
"
- if(isemptylist(news_network.network_channels))
- dat+="No feed channels found active...
"
- else
- for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
- dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
- dat+="
Cancel"
- if(11)
- dat+="Nanotrasen D-Notice Handler
"
- dat+="A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's"
- dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed"
- dat+="stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.
"
- if(isemptylist(news_network.network_channels))
- dat+="No feed channels found active...
"
- else
- for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
- dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
-
- dat+="
Back"
- if(12)
- dat+="[src.viewing_channel.channel_name]: \[ created by: [src.viewing_channel.author] \]
"
- dat+="[(src.viewing_channel.author=="\[REDACTED\]") ? ("Undo Author censorship") : ("Censor channel Author")]
"
-
-
- if( isemptylist(src.viewing_channel.messages) )
- dat+="No feed messages found in channel...
"
- else
- for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages)
- dat+="-[MESSAGE.body]
\[Story by [MESSAGE.author]\]
"
- dat+="[(MESSAGE.body == "\[REDACTED\]") ? ("Undo story censorship") : ("Censor story")] - [(MESSAGE.author == "\[REDACTED\]") ? ("Undo Author Censorship") : ("Censor message Author")]
"
- dat+="
Back"
- if(13)
- dat+="[src.viewing_channel.channel_name]: \[ created by: [src.viewing_channel.author] \]
"
- dat+="Channel messages listed below. If you deem them dangerous to the station, you can Bestow a D-Notice upon the channel.
"
- if(src.viewing_channel.censored)
- dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
- dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
- else
- if( isemptylist(src.viewing_channel.messages) )
- dat+="No feed messages found in channel...
"
- else
- for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages)
- dat+="-[MESSAGE.body]
\[Story by [MESSAGE.author]\]
"
-
- dat+="
Back"
- if(14)
- dat+="Wanted Issue Handler:"
- var/wanted_already = 0
- var/end_param = 1
- if(news_network.wanted_issue)
- wanted_already = 1
- end_param = 2
-
- if(wanted_already)
- dat+="
A wanted issue is already in Feed Circulation. You can edit or cancel it below."
- dat+="
"
- dat+="Criminal Name: [src.channel_name]
"
- dat+="Description: [src.msg]
"
- dat+="Attach Photo: [(src.photo ? "Photo Attached" : "No Photo")]"
- if(wanted_already)
- dat+="Wanted Issue created by: [news_network.wanted_issue.backup_author]
"
- else
- dat+="Wanted Issue will be created under prosecutor: [src.scanned_user]
"
- dat+="
[(wanted_already) ? ("Edit Issue") : ("Submit")]"
- if(wanted_already)
- dat+="
Take down Issue"
- dat+="
Cancel"
- if(15)
- dat+="Wanted issue for [src.channel_name] is now in Network Circulation.
"
- dat+="
Return
"
- if(16)
- dat+="ERROR: Wanted Issue rejected by Network.
"
- if(src.channel_name=="" || src.channel_name == "\[REDACTED\]")
- dat+="•Invalid name for person wanted.
"
- if(src.scanned_user=="Unknown")
- dat+="•Issue author unverified.
"
- if(src.msg == "" || src.msg == "\[REDACTED\]")
- dat+="•Invalid description.
"
- dat+="
Return
"
- if(17)
- dat+="Wanted Issue successfully deleted from Circulation
"
- dat+="
Return
"
- if(18)
- if(news_network.wanted_issue)
- dat+="-- STATIONWIDE WANTED ISSUE --
\[Submitted by: [news_network.wanted_issue.backup_author]\]
"
- dat+="Criminal: [news_network.wanted_issue.author]
"
- dat+="Description: [news_network.wanted_issue.body]
"
- dat+="Photo:: "
- if(news_network.wanted_issue.img)
- usr << browse_rsc(news_network.wanted_issue.img, "tmp_photow.png")
- dat+="
"
- else
- dat+="None"
- else
- dat+="No current wanted issue found.
"
- dat+="
Back
"
- if(19)
- dat+="Wanted issue for [src.channel_name] successfully edited.
"
- dat+="
Return
"
- if(20)
- dat+="Printing successful. Please receive your newspaper from the bottom of the machine.
"
- dat+="Return"
- if(21)
- dat+="Unable to print newspaper. Insufficient paper. Please notify maintenance personnel to refill machine storage.
"
- dat+="Return"
- else
- dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
-
- //human_or_robot_user << browse(dat, "window=newscaster_main;size=400x600")
- //onclose(human_or_robot_user, "newscaster_main")
-
- var/datum/browser/popup = new(human_or_robot_user, "newscaster_main", "Newscaster Unit #[src.unit_no]", 400, 600)
- popup.set_content(dat)
- popup.set_title_image(human_or_robot_user.browse_rsc_icon(src.icon, src.icon_state))
- popup.open()
-
-/obj/machinery/newscaster/Topic(href, href_list)
- if(..())
- return
- if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
- usr.set_machine(src)
- if(href_list["set_channel_name"])
- src.channel_name = strip_html_simple(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", ""))
- while (findtext(src.channel_name," ") == 1)
- src.channel_name = copytext(src.channel_name,2,lentext(src.channel_name)+1)
- src.updateUsrDialog()
- //src.update_icon()
-
- else if(href_list["set_channel_lock"])
- src.c_locked = !src.c_locked
- src.updateUsrDialog()
- //src.update_icon()
-
- else if(href_list["submit_new_channel"])
- var/list/existing_authors = list()
- for(var/datum/feed_channel/FC in news_network.network_channels)
- //existing_channels += FC.channel_name
- if(FC.author == "\[REDACTED\]")
- existing_authors += FC.backup_author
- else
- existing_authors +=FC.author
- var/check = 0
- for(var/datum/feed_channel/FC in news_network.network_channels)
- if(FC.channel_name == src.channel_name)
- check = 1
- break
- if(src.channel_name == "" || src.channel_name == "\[REDACTED\]" || src.scanned_user == "Unknown" || check || (src.scanned_user in existing_authors) )
- src.screen=7
- else
- var/choice = alert("Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel")
- if(choice=="Confirm")
- news_network.CreateFeedChannel(src.channel_name, src.scanned_user, c_locked)
- feedback_inc("newscaster_channels",1)
- src.screen=5
- src.updateUsrDialog()
- //src.update_icon()
-
- else if(href_list["set_channel_receiving"])
- //var/list/datum/feed_channel/available_channels = list()
- var/list/available_channels = list()
- for(var/datum/feed_channel/F in news_network.network_channels)
- if( (!F.locked || F.author == scanned_user) && !F.censored)
- available_channels += F.channel_name
- src.channel_name = input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels
- src.updateUsrDialog()
-
- else if(href_list["set_new_message"])
- src.msg = strip_html(input(usr, "Write your Feed story", "Network Channel Handler", ""))
- while (findtext(src.msg," ") == 1)
- src.msg = copytext(src.msg,2,lentext(src.msg)+1)
- src.updateUsrDialog()
-
- else if(href_list["set_attachment"])
- AttachPhoto(usr)
- src.updateUsrDialog()
-
- else if(href_list["submit_new_message"])
- if(src.msg =="" || src.msg=="\[REDACTED\]" || src.scanned_user == "Unknown" || src.channel_name == "" )
- src.screen=6
- else
- news_network.SubmitArticle(msg, scanned_user, channel_name, photo)
- feedback_inc("newscaster_stories",1)
- src.screen=4
- src.updateUsrDialog()
-
- else if(href_list["create_channel"])
- src.screen=2
- src.updateUsrDialog()
-
- else if(href_list["create_feed_story"])
- src.screen=3
- src.updateUsrDialog()
-
- else if(href_list["menu_paper"])
- src.screen=8
- src.updateUsrDialog()
- else if(href_list["print_paper"])
- if(!src.paper_remaining)
- src.screen=21
- else
- src.print_paper()
- src.screen = 20
- src.updateUsrDialog()
-
- else if(href_list["menu_censor_story"])
- src.screen=10
- src.updateUsrDialog()
-
- else if(href_list["menu_censor_channel"])
- src.screen=11
- src.updateUsrDialog()
-
- else if(href_list["menu_wanted"])
- var/already_wanted = 0
- if(news_network.wanted_issue)
- already_wanted = 1
-
- if(already_wanted)
- src.channel_name = news_network.wanted_issue.author
- src.msg = news_network.wanted_issue.body
- src.screen = 14
- src.updateUsrDialog()
-
- else if(href_list["set_wanted_name"])
- src.channel_name = strip_html(input(usr, "Provide the name of the Wanted person", "Network Security Handler", ""))
- while (findtext(src.channel_name," ") == 1)
- src.channel_name = copytext(src.channel_name,2,lentext(src.channel_name)+1)
- src.updateUsrDialog()
-
- else if(href_list["set_wanted_desc"])
- src.msg = strip_html(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", ""))
- while (findtext(src.msg," ") == 1)
- src.msg = copytext(src.msg,2,lentext(src.msg)+1)
- src.updateUsrDialog()
-
- else if(href_list["submit_wanted"])
- var/input_param = text2num(href_list["submit_wanted"])
- if(src.msg == "" || src.channel_name == "" || src.scanned_user == "Unknown")
- src.screen = 16
- else
- var/choice = alert("Please confirm Wanted Issue [(input_param==1) ? ("creation.") : ("edit.")]","Network Security Handler","Confirm","Cancel")
- if(choice=="Confirm")
- if(input_param==1) //If input_param == 1 we're submitting a new wanted issue. At 2 we're just editing an existing one. See the else below
- var/datum/feed_message/WANTED = new /datum/feed_message
- WANTED.author = src.channel_name
- WANTED.body = src.msg
- WANTED.backup_author = src.scanned_user //I know, a bit wacky
- if(photo)
- WANTED.img = photo.img
- news_network.wanted_issue = WANTED
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- NEWSCASTER.newsAlert()
- NEWSCASTER.update_icon()
- src.screen = 15
- else
- if(news_network.wanted_issue.is_admin_message)
- alert("The wanted issue has been distributed by a Nanotrasen higherup. You cannot edit it.","Ok")
- return
- news_network.wanted_issue.author = src.channel_name
- news_network.wanted_issue.body = src.msg
- news_network.wanted_issue.backup_author = src.scanned_user
- if(photo)
- news_network.wanted_issue.img = photo.img
- src.screen = 19
-
- src.updateUsrDialog()
-
- else if(href_list["cancel_wanted"])
- if(news_network.wanted_issue.is_admin_message)
- alert("The wanted issue has been distributed by a Nanotrasen higherup. You cannot take it down.","Ok")
- return
- var/choice = alert("Please confirm Wanted Issue removal","Network Security Handler","Confirm","Cancel")
- if(choice=="Confirm")
- news_network.wanted_issue = null
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- NEWSCASTER.update_icon()
- src.screen=17
- src.updateUsrDialog()
-
- else if(href_list["view_wanted"])
- src.screen=18
- src.updateUsrDialog()
- else if(href_list["censor_channel_author"])
- var/datum/feed_channel/FC = locate(href_list["censor_channel_author"])
- if(FC.is_admin_channel)
- alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
- return
- if(FC.author != "\[REDACTED\]")
- FC.backup_author = FC.author
- FC.author = "\[REDACTED\]"
- else
- FC.author = FC.backup_author
- src.updateUsrDialog()
-
- else if(href_list["censor_channel_story_author"])
- var/datum/feed_message/MSG = locate(href_list["censor_channel_story_author"])
- if(MSG.is_admin_message)
- alert("This message was created by a Nanotrasen Officer. You cannot censor its author.","Ok")
- return
- if(MSG.author != "\[REDACTED\]")
- MSG.backup_author = MSG.author
- MSG.author = "\[REDACTED\]"
- else
- MSG.author = MSG.backup_author
- src.updateUsrDialog()
-
- else if(href_list["censor_channel_story_body"])
- var/datum/feed_message/MSG = locate(href_list["censor_channel_story_body"])
- if(MSG.is_admin_message)
- alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
- return
- if(MSG.body != "\[REDACTED\]")
- MSG.backup_body = MSG.body
- MSG.body = "\[REDACTED\]"
- else
- MSG.body = MSG.backup_body
- src.updateUsrDialog()
-
- else if(href_list["pick_d_notice"])
- var/datum/feed_channel/FC = locate(href_list["pick_d_notice"])
- src.viewing_channel = FC
- src.screen=13
- src.updateUsrDialog()
-
- else if(href_list["toggle_d_notice"])
- var/datum/feed_channel/FC = locate(href_list["toggle_d_notice"])
- if(FC.is_admin_channel)
- alert("This channel was created by a Nanotrasen Officer. You cannot place a D-Notice upon it.","Ok")
- return
- FC.censored = !FC.censored
- src.updateUsrDialog()
-
- else if(href_list["view"])
- src.screen=1
- src.updateUsrDialog()
-
- else if(href_list["setScreen"]) //Brings us to the main menu and resets all fields~
- src.screen = text2num(href_list["setScreen"])
- if (src.screen == 0)
- src.scanned_user = "Unknown";
- msg = "";
- src.c_locked=0;
- channel_name="";
- src.viewing_channel = null
- src.updateUsrDialog()
-
- else if(href_list["show_channel"])
- var/datum/feed_channel/FC = locate(href_list["show_channel"])
- src.viewing_channel = FC
- src.screen = 9
- src.updateUsrDialog()
-
- else if(href_list["pick_censor_channel"])
- var/datum/feed_channel/FC = locate(href_list["pick_censor_channel"])
- src.viewing_channel = FC
- src.screen = 12
- src.updateUsrDialog()
-
- else if(href_list["refresh"])
- src.updateUsrDialog()
-
-
-/obj/machinery/newscaster/attackby(obj/item/I as obj, mob/user as mob)
-
-/* if (istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda) ) //Name verification for channels or messages
- if(src.screen == 4 || src.screen == 5)
- if( istype(I, /obj/item/device/pda) )
- var/obj/item/device/pda/P = I
- if(P.id)
- src.scanned_user = "[P.id.registered_name] ([P.id.assignment])"
- src.screen=2
- else
- var/obj/item/weapon/card/id/T = I
- src.scanned_user = text("[T.registered_name] ([T.assignment])")
- src.screen=2*/ //Obsolete after autorecognition
-
- if(istype(I, /obj/item/weapon/wrench))
- user << "Now [anchored ? "un" : ""]securing [name]"
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- if(do_after(user, 60))
- new /obj/item/newscaster_frame(loc)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
- qdel(src)
- return
-
- if (src.isbroken)
- playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 100, 1)
- for (var/mob/O in hearers(5, src.loc))
- O.show_message("[user.name] further abuses the shattered [src.name].")
- else
- if(istype(I, /obj/item/weapon) )
- var/obj/item/weapon/W = I
- if(W.force <15)
- for (var/mob/O in hearers(5, src.loc))
- O.show_message("[user.name] hits the [src.name] with the [W.name] with no visible effect." )
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 100, 1)
- else
- src.hitstaken++
- if(src.hitstaken==3)
- for (var/mob/O in hearers(5, src.loc))
- O.show_message("[user.name] smashes the [src.name]!" )
- src.isbroken=1
- playsound(src.loc, 'sound/effects/Glassbr3.ogg', 100, 1)
- else
- for (var/mob/O in hearers(5, src.loc))
- O.show_message("[user.name] forcefully slams the [src.name] with the [I.name]!" )
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 100, 1)
- else
- user << "This does nothing."
- src.update_icon()
-
-
-/obj/machinery/newscaster/attack_paw(mob/user as mob)
- user << "The newscaster controls are far too complicated for your tiny brain!"
- return
-
-/obj/machinery/newscaster/proc/AttachPhoto(mob/user as mob)
- if(photo)
- photo.loc = src.loc
- user.put_in_inactive_hand(photo)
- photo = null
- if(istype(user.get_active_hand(), /obj/item/weapon/photo))
- photo = user.get_active_hand()
- user.drop_item()
- photo.loc = src
- if(istype(usr,/mob/living/silicon/ai))
- var/list/nametemp = list()
- var/find
- var/datum/picture/selection
- var/mob/living/silicon/ai/tempAI = user
- if(tempAI.aicamera.aipictures.len == 0)
- usr << "No images saved"
- return
- for(var/datum/picture/t in tempAI.aicamera.aipictures)
- nametemp += t.fields["name"]
- find = input("Select image (numbered in order taken)") in nametemp
- var/obj/item/weapon/photo/P = new/obj/item/weapon/photo()
- for(var/datum/picture/q in tempAI.aicamera.aipictures)
- if(q.fields["name"] == find)
- selection = q
- break // just in case some AI decides to take 10 thousand pictures in a round
- P.icon = selection.fields["icon"]
- P.img = selection.fields["img"]
- P.desc = selection.fields["desc"]
- photo = P
-
-
-
-
-
-//########################################################################################################################
-//###################################### NEWSPAPER! ######################################################################
-//########################################################################################################################
-
-/obj/item/weapon/newspaper
- name = "newspaper"
- desc = "An issue of The Griffon, the newspaper circulating aboard Nanotrasen Space Stations."
- icon = 'icons/obj/bureaucracy.dmi'
- icon_state = "newspaper"
- w_class = 2 //Let's make it fit in trashbags!
- attack_verb = list("bapped")
- var/screen = 0
- var/pages = 0
- var/curr_page = 0
- var/list/datum/feed_channel/news_content = list()
- var/datum/feed_message/important_message = null
- var/scribble=""
- var/scribble_page = null
-
-/*obj/item/weapon/newspaper/attack_hand(mob/user as mob)
- ..()
- world << "derp"*/
-
-obj/item/weapon/newspaper/attack_self(mob/user as mob)
- if(ishuman(user))
- var/mob/living/carbon/human/human_user = user
- var/dat
- src.pages = 0
- switch(screen)
- if(0) //Cover
- dat+="The Griffon
"
- dat+="Nanotrasen-standard newspaper, for use on Nanotrasen© Space Facilities
"
- if(isemptylist(src.news_content))
- if(src.important_message)
- dat+="Contents:
**Important Security Announcement** \[page [src.pages+2]\]
"
- else
- dat+="Other than the title, the rest of the newspaper is unprinted..."
- else
- dat+="Contents:
"
- for(var/datum/feed_channel/NP in src.news_content)
- src.pages++
- if(src.important_message)
- dat+="**Important Security Announcement** \[page [src.pages+2]\]
"
- var/temp_page=0
- for(var/datum/feed_channel/NP in src.news_content)
- temp_page++
- dat+="[NP.channel_name] \[page [temp_page+1]\]
"
- dat+="
"
- if(scribble_page==curr_page)
- dat+="
There is a small scribble near the end of this page... It reads: \"[src.scribble]\""
- dat+= "
"
- if(1) // X channel pages inbetween.
- for(var/datum/feed_channel/NP in src.news_content)
- src.pages++ //Let's get it right again.
- var/datum/feed_channel/C = src.news_content[src.curr_page]
- dat+="[C.channel_name] \[created by: [C.author]\]
"
- if(C.censored)
- dat+="This channel was deemed dangerous to the general welfare of the station and therefore marked with a D-Notice. Its contents were not transferred to the newspaper at the time of printing."
- else
- if(isemptylist(C.messages))
- dat+="No Feed stories stem from this channel..."
- else
- dat+=""
- var/i = 0
- for(var/datum/feed_message/MESSAGE in C.messages)
- i++
- dat+="-[MESSAGE.body]
"
- if(MESSAGE.img)
- user << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
- dat+="
"
- dat+="\[Story by [MESSAGE.author]\]
"
- dat+="
"
- if(scribble_page==curr_page)
- dat+="
There is a small scribble near the end of this page... It reads: \"[src.scribble]\""
- dat+= "
"
- if(2) //Last page
- for(var/datum/feed_channel/NP in src.news_content)
- src.pages++
- if(src.important_message!=null)
- dat+="Wanted Issue:
"
- dat+="Criminal name: [important_message.author]
"
- dat+="Description: [important_message.body]
"
- dat+="Photo:: "
- if(important_message.img)
- user << browse_rsc(important_message.img, "tmp_photow.png")
- dat+="
"
- else
- dat+="None"
- else
- dat+="Apart from some uninteresting Classified ads, there's nothing on this page..."
- if(scribble_page==curr_page)
- dat+="
There is a small scribble near the end of this page... It reads: \"[src.scribble]\""
- dat+= "
"
- else
- dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
-
- dat+="
[src.curr_page+1]
"
- human_user << browse(dat, "window=newspaper_main;size=300x400")
- onclose(human_user, "newspaper_main")
- else
- user << "The paper is full of intelligible symbols!"
-
-
-obj/item/weapon/newspaper/Topic(href, href_list)
- var/mob/living/U = usr
- ..()
- if ((src in U.contents) || ( istype(loc, /turf) && in_range(src, U) ))
- U.set_machine(src)
- if(href_list["next_page"])
- if(curr_page==src.pages+1)
- return //Don't need that at all, but anyway.
- if(src.curr_page == src.pages) //We're at the middle, get to the end
- src.screen = 2
- else
- if(curr_page == 0) //We're at the start, get to the middle
- src.screen=1
- src.curr_page++
- playsound(src.loc, "pageturn", 50, 1)
-
- else if(href_list["prev_page"])
- if(curr_page == 0)
- return
- if(curr_page == 1)
- src.screen = 0
-
- else
- if(curr_page == src.pages+1) //we're at the end, let's go back to the middle.
- src.screen = 1
- src.curr_page--
- playsound(src.loc, "pageturn", 50, 1)
-
- if (istype(src.loc, /mob))
- src.attack_self(src.loc)
-
-
-obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W, /obj/item/weapon/pen))
- if(src.scribble_page == src.curr_page)
- user << "There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?"
- else
- var/s = strip_html( input(user, "Write something", "Newspaper", "") )
- s = copytext(sanitize(s), 1, MAX_MESSAGE_LEN)
- if (!s)
- return
- if (!in_range(src, usr) && src.loc != usr)
- return
- src.scribble_page = src.curr_page
- src.scribble = s
- src.attack_self(user)
- return
-
-
-////////////////////////////////////helper procs
-
-
-/obj/machinery/newscaster/proc/scan_user(mob/living/user as mob)
- if(istype(user,/mob/living/carbon/human)) //User is a human
- var/mob/living/carbon/human/human_user = user
- if(human_user.wear_id) //Newscaster scans you
- if(istype(human_user.wear_id, /obj/item/device/pda) ) //autorecognition, woo!
- var/obj/item/device/pda/P = human_user.wear_id
- if(P.id)
- src.scanned_user = "[P.id.registered_name] ([P.id.assignment])"
- else
- src.scanned_user = "Unknown"
- else if(istype(human_user.wear_id, /obj/item/weapon/card/id) )
- var/obj/item/weapon/card/id/ID = human_user.wear_id
- src.scanned_user ="[ID.registered_name] ([ID.assignment])"
- else
- src.scanned_user ="Unknown"
- else
- src.scanned_user ="Unknown"
- else
- var/mob/living/silicon/ai_user = user
- src.scanned_user = "[ai_user.name] ([ai_user.job])"
-
-
-/obj/machinery/newscaster/proc/print_paper()
- feedback_inc("newscaster_newspapers_printed",1)
- var/obj/item/weapon/newspaper/NEWSPAPER = new /obj/item/weapon/newspaper
- for(var/datum/feed_channel/FC in news_network.network_channels)
- NEWSPAPER.news_content += FC
- if(news_network.wanted_issue)
- NEWSPAPER.important_message = news_network.wanted_issue
- NEWSPAPER.loc = get_turf(src)
- src.paper_remaining--
- return
-
-//Removed for now so these aren't even checked every tick. Left this here in-case Agouri needs it later.
-///obj/machinery/newscaster/process() //Was thinking of doing the icon update through process, but multiple iterations per second does not
-// return //bode well with a newscaster network of 10+ machines. Let's just return it, as it's added in the machines list.
-
-/obj/machinery/newscaster/proc/newsAlert(channel) //This isn't Agouri's work, for it is ugly and vile.
- var/turf/T = get_turf(src) //Who the fuck uses spawn(600) anyway, jesus christ
- if(channel)
- for(var/mob/O in hearers(world.view-1, T))
- O.show_message("[src.name] beeps, \"Breaking news from [channel]!\"",2)
- src.alert = 1
- src.update_icon()
- spawn(300)
- src.alert = 0
- src.update_icon()
- playsound(src.loc, 'sound/machines/twobeep.ogg', 75, 1)
- else
- for(var/mob/O in hearers(world.view-1, T))
- O.show_message("[src.name] beeps, \"Attention! Wanted issue distributed!\"",2)
- playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 75, 1)
+//##############################################
+//################### NEWSCASTERS BE HERE! ####
+//###-Agouri###################################
+
+/datum/feed_message
+ var/author =""
+ var/body =""
+ //var/parent_channel
+ var/backup_body =""
+ var/backup_author =""
+ var/is_admin_message = 0
+ var/icon/img = null
+ var/time_stamp = ""
+
+/datum/feed_channel
+ var/channel_name=""
+ var/list/datum/feed_message/messages = list()
+ //var/message_count = 0
+ var/locked=0
+ var/author=""
+ var/backup_author=""
+ var/censored=0
+ var/is_admin_channel=0
+ //var/page = null //For newspapers
+
+/datum/feed_message/proc/clear()
+ src.author = ""
+ src.body = ""
+ src.backup_body = ""
+ src.backup_author = ""
+ src.img = null
+
+/datum/feed_channel/proc/clear()
+ src.channel_name = ""
+ src.messages = list()
+ src.locked = 0
+ src.author = ""
+ src.backup_author = ""
+ src.censored = 0
+ src.is_admin_channel = 0
+
+/datum/feed_network
+ var/list/datum/feed_channel/network_channels = list()
+ var/datum/feed_message/wanted_issue
+
+/datum/feed_network/New()
+ CreateFeedChannel("Central Command", "Centcom Official", 1)
+
+/datum/feed_network/proc/CreateFeedChannel(var/channel_name, var/author, var/locked, var/adminChannel = 0)
+ var/datum/feed_channel/newChannel = new /datum/feed_channel
+ newChannel.channel_name = channel_name
+ newChannel.author = author
+ newChannel.locked = locked
+ newChannel.is_admin_channel = adminChannel
+ network_channels += newChannel
+
+/datum/feed_network/proc/SubmitArticle(var/msg, var/author, var/channel_name, var/obj/item/weapon/photo/photo, var/adminMessage = 0)
+ var/datum/feed_message/newMsg = new /datum/feed_message
+ newMsg.author = author
+ newMsg.body = msg
+ newMsg.time_stamp = "[worldtime2text()]"
+ newMsg.is_admin_message = adminMessage
+ if(photo)
+ newMsg.img = photo.img
+ for(var/datum/feed_channel/FC in network_channels)
+ if(FC.channel_name == channel_name)
+ FC.messages += newMsg //Adding message to the network's appropriate feed_channel
+ break
+ for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
+ NEWSCASTER.newsAlert(channel_name)
+
+
+var/datum/feed_network/news_network = new /datum/feed_network //The global news-network, which is coincidentally a global list.
+
+var/list/obj/machinery/newscaster/allCasters = list() //Global list that will contain reference to all newscasters in existence.
+
+
+/obj/item/newscaster_frame
+ name = "newscaster frame"
+ desc = "Used to build newscasters, just secure to the wall."
+ icon_state = "newscaster"
+ item_state = "syringe_kit"
+ m_amt = 14000
+ g_amt = 8000
+
+/obj/item/newscaster_frame/proc/try_build(turf/on_wall)
+ if (get_dist(on_wall,usr)>1)
+ return
+ var/ndir = get_dir(usr,on_wall)
+ if (!(ndir in cardinal))
+ return
+ var/turf/loc = get_turf(usr)
+ var/area/A = loc.loc
+ if (!istype(loc, /turf/simulated/floor))
+ usr << "Newscaster cannot be placed on this spot."
+ return
+ if (A.requires_power == 0 || A.name == "Space")
+ usr << "Newscaster cannot be placed in this area."
+ return
+ for(var/obj/machinery/newscaster/T in loc)
+ usr << "There is another newscaster here."
+ return
+ var/obj/machinery/newscaster/N = new(loc)
+ N.pixel_y -= (loc.y - on_wall.y) * 32
+ N.pixel_x -= (loc.x - on_wall.x) * 32
+ qdel(src)
+
+
+
+
+/obj/machinery/newscaster
+ name = "newscaster"
+ desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!"
+ icon = 'icons/obj/terminals.dmi'
+ icon_state = "newscaster_normal"
+ var/isbroken = 0 //1 if someone banged it with something heavy
+ var/ispowered = 1 //starts powered, changes with power_change()
+ //var/list/datum/feed_channel/channel_list = list() //This list will contain the names of the feed channels. Each name will refer to a data region where the messages of the feed channels are stored.
+ //OBSOLETE: We're now using a global news network
+ var/screen = 0
+ // 0 = welcome screen - main menu
+ // 1 = view feed channels
+ // 2 = create feed channel
+ // 3 = create feed story
+ // 4 = feed story submited sucessfully
+ // 5 = feed channel created successfully
+ // 6 = ERROR: Cannot create feed story
+ // 7 = ERROR: Cannot create feed channel
+ // 8 = print newspaper
+ // 9 = viewing channel feeds
+ // 10 = censor feed story
+ // 11 = censor feed channel
+ //Holy shit this is outdated, made this when I was still starting newscasters :3
+ var/paper_remaining = 0
+ var/securityCaster = 0
+ // 0 = Caster cannot be used to issue wanted posters
+ // 1 = the opposite
+ var/unit_no = 0 //Each newscaster has a unit number
+ //var/datum/feed_message/wanted //We're gonna use a feed_message to store data of the wanted person because fields are similar
+ //var/wanted_issue = 0 //OBSOLETE
+ // 0 = there's no WANTED issued, we don't need a special icon_state
+ // 1 = Guess what.
+ var/alert_delay = 500
+ var/alert = 0
+ // 0 = there hasn't been a news/wanted update in the last alert_delay
+ // 1 = there has
+ var/scanned_user = "Unknown" //Will contain the name of the person who currently uses the newscaster
+ var/msg = ""; //Feed message
+ var/obj/item/weapon/photo/photo = null
+ var/channel_name = ""; //the feed channel which will be receiving the feed, or being created
+ var/c_locked=0; //Will our new channel be locked to public submissions?
+ var/hitstaken = 0 //Death at 3 hits from an item with force>=15
+ var/datum/feed_channel/viewing_channel = null
+ luminosity = 0
+ anchored = 1
+
+
+/obj/machinery/newscaster/security_unit //Security unit
+ name = "security newscaster"
+ securityCaster = 1
+
+/obj/machinery/newscaster/New()
+ allCasters += src
+ src.paper_remaining = 15
+ for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
+ src.unit_no++
+ src.update_icon() //for any custom ones on the map...
+ ..() //I just realised the newscasters weren't in the global machines list. The superconstructor call will tend to that
+
+/obj/machinery/newscaster/Destroy()
+ allCasters -= src
+ ..()
+
+/obj/machinery/newscaster/update_icon()
+ if(!ispowered || isbroken)
+ icon_state = "newscaster_off"
+ if(isbroken) //If the thing is smashed, add crack overlay on top of the unpowered sprite.
+ src.overlays.Cut()
+ src.overlays += image(src.icon, "crack3")
+ return
+
+ src.overlays.Cut() //reset overlays
+
+ if(news_network.wanted_issue) //wanted icon state, there can be no overlays on it as it's a priority message
+ icon_state = "newscaster_wanted"
+ return
+
+ if(alert) //new message alert overlay
+ src.overlays += "newscaster_alert"
+
+ if(hitstaken > 0) //Cosmetic damage overlay
+ src.overlays += image(src.icon, "crack[hitstaken]")
+
+ icon_state = "newscaster_normal"
+ return
+
+/obj/machinery/newscaster/power_change()
+ if(isbroken) //Broken shit can't be powered.
+ return
+ if( src.powered() )
+ src.ispowered = 1
+ stat &= ~NOPOWER
+ src.update_icon()
+ else
+ spawn(rand(0, 15))
+ src.ispowered = 0
+ stat |= NOPOWER
+ src.update_icon()
+
+
+/obj/machinery/newscaster/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ qdel(src)
+ return
+ if(2.0)
+ src.isbroken=1
+ if(prob(50))
+ qdel(src)
+ else
+ src.update_icon() //can't place it above the return and outside the if-else. or we might get runtimes of null.update_icon() if(prob(50)) goes in.
+ return
+ else
+ if(prob(50))
+ src.isbroken=1
+ src.update_icon()
+ return
+ return
+
+/obj/machinery/newscaster/attack_ai(mob/user as mob)
+ return src.attack_hand(user)
+
+/obj/machinery/newscaster/attack_hand(mob/user as mob) //########### THE MAIN BEEF IS HERE! And in the proc below this...############
+ if(!src.ispowered || src.isbroken)
+ return
+ if(istype(user, /mob/living/carbon/human) || istype(user,/mob/living/silicon) )
+ var/mob/living/human_or_robot_user = user
+ var/dat
+
+ src.scan_user(human_or_robot_user) //Newscaster scans you
+
+ switch(screen)
+ if(0)
+ dat += "Welcome to Newscasting Unit #[src.unit_no].
Interface & News networks Operational."
+ dat += "
Property of Nanotransen Inc"
+ if(news_network.wanted_issue)
+ dat+= "
Read Wanted Issue"
+ dat+= "
Create Feed Channel"
+ dat+= "
View Feed Channels"
+ dat+= "
Submit new Feed story"
+ dat+= "
Print newspaper"
+ dat+= "
Re-scan User"
+ dat+= "
Exit"
+ if(src.securityCaster)
+ var/wanted_already = 0
+ if(news_network.wanted_issue)
+ wanted_already = 1
+
+ dat+="
Feed Security functions:
"
+ dat+="
[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue"
+ dat+="
Censor Feed Stories"
+ dat+="
Mark Feed Channel with Nanotrasen D-Notice"
+ dat+="
The newscaster recognises you as: [src.scanned_user]"
+ if(1)
+ dat+= "Station Feed Channels
"
+ if( isemptylist(news_network.network_channels) )
+ dat+="No active channels found..."
+ else
+ for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
+ if(CHANNEL.is_admin_channel)
+ dat+="[CHANNEL.channel_name]
"
+ else
+ dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
+ /*for(var/datum/feed_channel/CHANNEL in src.channel_list)
+ dat+="[CHANNEL.channel_name]:
\[created by: [CHANNEL.author]\]
"
+ if( isemptylist(CHANNEL.messages) )
+ dat+="No feed messages found in channel...
"
+ else
+ for(var/datum/feed_message/MESSAGE in CHANNEL.messages)
+ dat+="-[MESSAGE.body]
\[Story by [MESSAGE.author]\]
"*/
+
+ dat+="
Refresh"
+ dat+="
Back"
+ if(2)
+ dat+="Creating new Feed Channel..."
+ dat+="
Channel Name: [src.channel_name]
"
+ dat+="Channel Author: [src.scanned_user]
"
+ dat+="Will Accept Public Feeds: [(src.c_locked) ? ("NO") : ("YES")]
"
+ dat+="
Submit
Cancel
"
+ if(3)
+ dat+="Creating new Feed Message..."
+ dat+="
Receiving Channel: [src.channel_name]
" //MARK
+ dat+="Message Author: [src.scanned_user]
"
+ dat+="Message Body: [src.msg]
"
+ dat+="Attach Photo: [(src.photo ? "Photo Attached" : "No Photo")]"
+ dat+="
Submit
Cancel
"
+ if(4)
+ dat+="Feed story successfully submitted to [src.channel_name].
"
+ dat+="
Return
"
+ if(5)
+ dat+="Feed Channel [src.channel_name] created successfully.
"
+ dat+="
Return
"
+ if(6)
+ dat+="ERROR: Could not submit Feed story to Network.
"
+ if(src.channel_name=="")
+ dat+="•Invalid receiving channel name.
"
+ if(src.scanned_user=="Unknown")
+ dat+="•Channel author unverified.
"
+ if(src.msg == "" || src.msg == "\[REDACTED\]")
+ dat+="•Invalid message body.
"
+
+ dat+="
Return
"
+ if(7)
+ dat+="ERROR: Could not submit Feed Channel to Network.
"
+ //var/list/existing_channels = list() //Let's get dem existing channels - OBSOLETE
+ var/list/existing_authors = list()
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ //existing_channels += FC.channel_name //OBSOLETE
+ if(FC.author == "\[REDACTED\]")
+ existing_authors += FC.backup_author
+ else
+ existing_authors += FC.author
+ if(src.scanned_user in existing_authors)
+ dat+="•There already exists a Feed channel under your name.
"
+ if(src.channel_name=="" || src.channel_name == "\[REDACTED\]")
+ dat+="•Invalid channel name.
"
+ var/check = 0
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ if(FC.channel_name == src.channel_name)
+ check = 1
+ break
+ if(check)
+ dat+="•Channel name already in use.
"
+ if(src.scanned_user=="Unknown")
+ dat+="•Channel author unverified.
"
+ dat+="
Return
"
+ if(8)
+ var/total_num=length(news_network.network_channels)
+ var/active_num=total_num
+ var/message_num=0
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ if(!FC.censored)
+ message_num += length(FC.messages) //Dont forget, datum/feed_channel's var messages is a list of datum/feed_message
+ else
+ active_num--
+ dat+="Network currently serves a total of [total_num] Feed channels, [active_num] of which are active, and a total of [message_num] Feed Stories." //TODO: CONTINUE
+ dat+="
Liquid Paper remaining: [(src.paper_remaining) *100 ] cm^3"
+ dat+="
Print Paper"
+ dat+="
Cancel"
+ if(9)
+ dat+="[src.viewing_channel.channel_name]: \[created by: [src.viewing_channel.author]\]
"
+ if(src.viewing_channel.censored)
+ dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
+ dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
+ else
+ if( isemptylist(src.viewing_channel.messages) )
+ dat+="No feed messages found in channel...
"
+ else
+ var/i = 0
+ for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages)
+ i++
+ dat+="-[MESSAGE.body]
"
+ if(MESSAGE.img)
+ usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
+ dat+="
"
+ dat+="\[Story by [MESSAGE.author] \] - ([MESSAGE.time_stamp])
"
+ dat+="
Refresh"
+ dat+="
Back"
+ if(10)
+ dat+="Nanotrasen Feed Censorship Tool
"
+ dat+="NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.
"
+ dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it."
+ dat+="
Select Feed channel to get Stories from:
"
+ if(isemptylist(news_network.network_channels))
+ dat+="No feed channels found active...
"
+ else
+ for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
+ dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
+ dat+="
Cancel"
+ if(11)
+ dat+="Nanotrasen D-Notice Handler
"
+ dat+="A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's"
+ dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed"
+ dat+="stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.
"
+ if(isemptylist(news_network.network_channels))
+ dat+="No feed channels found active...
"
+ else
+ for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
+ dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
+
+ dat+="
Back"
+ if(12)
+ dat+="[src.viewing_channel.channel_name]: \[ created by: [src.viewing_channel.author] \]
"
+ dat+="[(src.viewing_channel.author=="\[REDACTED\]") ? ("Undo Author censorship") : ("Censor channel Author")]
"
+
+
+ if( isemptylist(src.viewing_channel.messages) )
+ dat+="No feed messages found in channel...
"
+ else
+ for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages)
+ dat+="-[MESSAGE.body]
\[Story by [MESSAGE.author]\]
"
+ dat+="[(MESSAGE.body == "\[REDACTED\]") ? ("Undo story censorship") : ("Censor story")] - [(MESSAGE.author == "\[REDACTED\]") ? ("Undo Author Censorship") : ("Censor message Author")]
"
+ dat+="
Back"
+ if(13)
+ dat+="[src.viewing_channel.channel_name]: \[ created by: [src.viewing_channel.author] \]
"
+ dat+="Channel messages listed below. If you deem them dangerous to the station, you can Bestow a D-Notice upon the channel.
"
+ if(src.viewing_channel.censored)
+ dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
+ dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
+ else
+ if( isemptylist(src.viewing_channel.messages) )
+ dat+="No feed messages found in channel...
"
+ else
+ for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages)
+ dat+="-[MESSAGE.body]
\[Story by [MESSAGE.author]\]
"
+
+ dat+="
Back"
+ if(14)
+ dat+="Wanted Issue Handler:"
+ var/wanted_already = 0
+ var/end_param = 1
+ if(news_network.wanted_issue)
+ wanted_already = 1
+ end_param = 2
+
+ if(wanted_already)
+ dat+="
A wanted issue is already in Feed Circulation. You can edit or cancel it below."
+ dat+="
"
+ dat+="Criminal Name: [src.channel_name]
"
+ dat+="Description: [src.msg]
"
+ dat+="Attach Photo: [(src.photo ? "Photo Attached" : "No Photo")]"
+ if(wanted_already)
+ dat+="Wanted Issue created by: [news_network.wanted_issue.backup_author]
"
+ else
+ dat+="Wanted Issue will be created under prosecutor: [src.scanned_user]
"
+ dat+="
[(wanted_already) ? ("Edit Issue") : ("Submit")]"
+ if(wanted_already)
+ dat+="
Take down Issue"
+ dat+="
Cancel"
+ if(15)
+ dat+="Wanted issue for [src.channel_name] is now in Network Circulation.
"
+ dat+="
Return
"
+ if(16)
+ dat+="ERROR: Wanted Issue rejected by Network.
"
+ if(src.channel_name=="" || src.channel_name == "\[REDACTED\]")
+ dat+="•Invalid name for person wanted.
"
+ if(src.scanned_user=="Unknown")
+ dat+="•Issue author unverified.
"
+ if(src.msg == "" || src.msg == "\[REDACTED\]")
+ dat+="•Invalid description.
"
+ dat+="
Return
"
+ if(17)
+ dat+="Wanted Issue successfully deleted from Circulation
"
+ dat+="
Return
"
+ if(18)
+ if(news_network.wanted_issue)
+ dat+="-- STATIONWIDE WANTED ISSUE --
\[Submitted by: [news_network.wanted_issue.backup_author]\]
"
+ dat+="Criminal: [news_network.wanted_issue.author]
"
+ dat+="Description: [news_network.wanted_issue.body]
"
+ dat+="Photo:: "
+ if(news_network.wanted_issue.img)
+ usr << browse_rsc(news_network.wanted_issue.img, "tmp_photow.png")
+ dat+="
"
+ else
+ dat+="None"
+ else
+ dat+="No current wanted issue found.
"
+ dat+="
Back
"
+ if(19)
+ dat+="Wanted issue for [src.channel_name] successfully edited.
"
+ dat+="
Return
"
+ if(20)
+ dat+="Printing successful. Please receive your newspaper from the bottom of the machine.
"
+ dat+="Return"
+ if(21)
+ dat+="Unable to print newspaper. Insufficient paper. Please notify maintenance personnel to refill machine storage.
"
+ dat+="Return"
+ else
+ dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
+
+ //human_or_robot_user << browse(dat, "window=newscaster_main;size=400x600")
+ //onclose(human_or_robot_user, "newscaster_main")
+
+ var/datum/browser/popup = new(human_or_robot_user, "newscaster_main", "Newscaster Unit #[src.unit_no]", 400, 600)
+ popup.set_content(dat)
+ popup.set_title_image(human_or_robot_user.browse_rsc_icon(src.icon, src.icon_state))
+ popup.open()
+
+/obj/machinery/newscaster/Topic(href, href_list)
+ if(..())
+ return
+ if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
+ usr.set_machine(src)
+ if(href_list["set_channel_name"])
+ src.channel_name = strip_html_simple(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", ""))
+ while (findtext(src.channel_name," ") == 1)
+ src.channel_name = copytext(src.channel_name,2,lentext(src.channel_name)+1)
+ src.updateUsrDialog()
+ //src.update_icon()
+
+ else if(href_list["set_channel_lock"])
+ src.c_locked = !src.c_locked
+ src.updateUsrDialog()
+ //src.update_icon()
+
+ else if(href_list["submit_new_channel"])
+ var/list/existing_authors = list()
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ //existing_channels += FC.channel_name
+ if(FC.author == "\[REDACTED\]")
+ existing_authors += FC.backup_author
+ else
+ existing_authors +=FC.author
+ var/check = 0
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ if(FC.channel_name == src.channel_name)
+ check = 1
+ break
+ if(src.channel_name == "" || src.channel_name == "\[REDACTED\]" || src.scanned_user == "Unknown" || check || (src.scanned_user in existing_authors) )
+ src.screen=7
+ else
+ var/choice = alert("Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel")
+ if(choice=="Confirm")
+ news_network.CreateFeedChannel(src.channel_name, src.scanned_user, c_locked)
+ feedback_inc("newscaster_channels",1)
+ src.screen=5
+ src.updateUsrDialog()
+ //src.update_icon()
+
+ else if(href_list["set_channel_receiving"])
+ //var/list/datum/feed_channel/available_channels = list()
+ var/list/available_channels = list()
+ for(var/datum/feed_channel/F in news_network.network_channels)
+ if( (!F.locked || F.author == scanned_user) && !F.censored)
+ available_channels += F.channel_name
+ src.channel_name = input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels
+ src.updateUsrDialog()
+
+ else if(href_list["set_new_message"])
+ src.msg = strip_html(input(usr, "Write your Feed story", "Network Channel Handler", ""))
+ while (findtext(src.msg," ") == 1)
+ src.msg = copytext(src.msg,2,lentext(src.msg)+1)
+ src.updateUsrDialog()
+
+ else if(href_list["set_attachment"])
+ AttachPhoto(usr)
+ src.updateUsrDialog()
+
+ else if(href_list["submit_new_message"])
+ if(src.msg =="" || src.msg=="\[REDACTED\]" || src.scanned_user == "Unknown" || src.channel_name == "" )
+ src.screen=6
+ else
+ news_network.SubmitArticle(msg, scanned_user, channel_name, photo)
+ feedback_inc("newscaster_stories",1)
+ src.screen=4
+ src.updateUsrDialog()
+
+ else if(href_list["create_channel"])
+ src.screen=2
+ src.updateUsrDialog()
+
+ else if(href_list["create_feed_story"])
+ src.screen=3
+ src.updateUsrDialog()
+
+ else if(href_list["menu_paper"])
+ src.screen=8
+ src.updateUsrDialog()
+ else if(href_list["print_paper"])
+ if(!src.paper_remaining)
+ src.screen=21
+ else
+ src.print_paper()
+ src.screen = 20
+ src.updateUsrDialog()
+
+ else if(href_list["menu_censor_story"])
+ src.screen=10
+ src.updateUsrDialog()
+
+ else if(href_list["menu_censor_channel"])
+ src.screen=11
+ src.updateUsrDialog()
+
+ else if(href_list["menu_wanted"])
+ var/already_wanted = 0
+ if(news_network.wanted_issue)
+ already_wanted = 1
+
+ if(already_wanted)
+ src.channel_name = news_network.wanted_issue.author
+ src.msg = news_network.wanted_issue.body
+ src.screen = 14
+ src.updateUsrDialog()
+
+ else if(href_list["set_wanted_name"])
+ src.channel_name = strip_html(input(usr, "Provide the name of the Wanted person", "Network Security Handler", ""))
+ while (findtext(src.channel_name," ") == 1)
+ src.channel_name = copytext(src.channel_name,2,lentext(src.channel_name)+1)
+ src.updateUsrDialog()
+
+ else if(href_list["set_wanted_desc"])
+ src.msg = strip_html(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", ""))
+ while (findtext(src.msg," ") == 1)
+ src.msg = copytext(src.msg,2,lentext(src.msg)+1)
+ src.updateUsrDialog()
+
+ else if(href_list["submit_wanted"])
+ var/input_param = text2num(href_list["submit_wanted"])
+ if(src.msg == "" || src.channel_name == "" || src.scanned_user == "Unknown")
+ src.screen = 16
+ else
+ var/choice = alert("Please confirm Wanted Issue [(input_param==1) ? ("creation.") : ("edit.")]","Network Security Handler","Confirm","Cancel")
+ if(choice=="Confirm")
+ if(input_param==1) //If input_param == 1 we're submitting a new wanted issue. At 2 we're just editing an existing one. See the else below
+ var/datum/feed_message/WANTED = new /datum/feed_message
+ WANTED.author = src.channel_name
+ WANTED.body = src.msg
+ WANTED.backup_author = src.scanned_user //I know, a bit wacky
+ if(photo)
+ WANTED.img = photo.img
+ news_network.wanted_issue = WANTED
+ for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
+ NEWSCASTER.newsAlert()
+ NEWSCASTER.update_icon()
+ src.screen = 15
+ else
+ if(news_network.wanted_issue.is_admin_message)
+ alert("The wanted issue has been distributed by a Nanotrasen higherup. You cannot edit it.","Ok")
+ return
+ news_network.wanted_issue.author = src.channel_name
+ news_network.wanted_issue.body = src.msg
+ news_network.wanted_issue.backup_author = src.scanned_user
+ if(photo)
+ news_network.wanted_issue.img = photo.img
+ src.screen = 19
+
+ src.updateUsrDialog()
+
+ else if(href_list["cancel_wanted"])
+ if(news_network.wanted_issue.is_admin_message)
+ alert("The wanted issue has been distributed by a Nanotrasen higherup. You cannot take it down.","Ok")
+ return
+ var/choice = alert("Please confirm Wanted Issue removal","Network Security Handler","Confirm","Cancel")
+ if(choice=="Confirm")
+ news_network.wanted_issue = null
+ for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
+ NEWSCASTER.update_icon()
+ src.screen=17
+ src.updateUsrDialog()
+
+ else if(href_list["view_wanted"])
+ src.screen=18
+ src.updateUsrDialog()
+ else if(href_list["censor_channel_author"])
+ var/datum/feed_channel/FC = locate(href_list["censor_channel_author"])
+ if(FC.is_admin_channel)
+ alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
+ return
+ if(FC.author != "\[REDACTED\]")
+ FC.backup_author = FC.author
+ FC.author = "\[REDACTED\]"
+ else
+ FC.author = FC.backup_author
+ src.updateUsrDialog()
+
+ else if(href_list["censor_channel_story_author"])
+ var/datum/feed_message/MSG = locate(href_list["censor_channel_story_author"])
+ if(MSG.is_admin_message)
+ alert("This message was created by a Nanotrasen Officer. You cannot censor its author.","Ok")
+ return
+ if(MSG.author != "\[REDACTED\]")
+ MSG.backup_author = MSG.author
+ MSG.author = "\[REDACTED\]"
+ else
+ MSG.author = MSG.backup_author
+ src.updateUsrDialog()
+
+ else if(href_list["censor_channel_story_body"])
+ var/datum/feed_message/MSG = locate(href_list["censor_channel_story_body"])
+ if(MSG.is_admin_message)
+ alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
+ return
+ if(MSG.body != "\[REDACTED\]")
+ MSG.backup_body = MSG.body
+ MSG.body = "\[REDACTED\]"
+ else
+ MSG.body = MSG.backup_body
+ src.updateUsrDialog()
+
+ else if(href_list["pick_d_notice"])
+ var/datum/feed_channel/FC = locate(href_list["pick_d_notice"])
+ src.viewing_channel = FC
+ src.screen=13
+ src.updateUsrDialog()
+
+ else if(href_list["toggle_d_notice"])
+ var/datum/feed_channel/FC = locate(href_list["toggle_d_notice"])
+ if(FC.is_admin_channel)
+ alert("This channel was created by a Nanotrasen Officer. You cannot place a D-Notice upon it.","Ok")
+ return
+ FC.censored = !FC.censored
+ src.updateUsrDialog()
+
+ else if(href_list["view"])
+ src.screen=1
+ src.updateUsrDialog()
+
+ else if(href_list["setScreen"]) //Brings us to the main menu and resets all fields~
+ src.screen = text2num(href_list["setScreen"])
+ if (src.screen == 0)
+ src.scanned_user = "Unknown";
+ msg = "";
+ src.c_locked=0;
+ channel_name="";
+ src.viewing_channel = null
+ src.updateUsrDialog()
+
+ else if(href_list["show_channel"])
+ var/datum/feed_channel/FC = locate(href_list["show_channel"])
+ src.viewing_channel = FC
+ src.screen = 9
+ src.updateUsrDialog()
+
+ else if(href_list["pick_censor_channel"])
+ var/datum/feed_channel/FC = locate(href_list["pick_censor_channel"])
+ src.viewing_channel = FC
+ src.screen = 12
+ src.updateUsrDialog()
+
+ else if(href_list["refresh"])
+ src.updateUsrDialog()
+
+
+/obj/machinery/newscaster/attackby(obj/item/I as obj, mob/user as mob)
+
+/* if (istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda) ) //Name verification for channels or messages
+ if(src.screen == 4 || src.screen == 5)
+ if( istype(I, /obj/item/device/pda) )
+ var/obj/item/device/pda/P = I
+ if(P.id)
+ src.scanned_user = "[P.id.registered_name] ([P.id.assignment])"
+ src.screen=2
+ else
+ var/obj/item/weapon/card/id/T = I
+ src.scanned_user = text("[T.registered_name] ([T.assignment])")
+ src.screen=2*/ //Obsolete after autorecognition
+
+ if(istype(I, /obj/item/weapon/wrench))
+ user << "Now [anchored ? "un" : ""]securing [name]"
+ playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ if(do_after(user, 60))
+ new /obj/item/newscaster_frame(loc)
+ playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ qdel(src)
+ return
+
+ if (src.isbroken)
+ playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 100, 1)
+ for (var/mob/O in hearers(5, src.loc))
+ O.show_message("[user.name] further abuses the shattered [src.name].")
+ else
+ if(istype(I, /obj/item/weapon) )
+ var/obj/item/weapon/W = I
+ if(W.force <15)
+ for (var/mob/O in hearers(5, src.loc))
+ O.show_message("[user.name] hits the [src.name] with the [W.name] with no visible effect." )
+ playsound(src.loc, 'sound/effects/Glasshit.ogg', 100, 1)
+ else
+ src.hitstaken++
+ if(src.hitstaken==3)
+ for (var/mob/O in hearers(5, src.loc))
+ O.show_message("[user.name] smashes the [src.name]!" )
+ src.isbroken=1
+ playsound(src.loc, 'sound/effects/Glassbr3.ogg', 100, 1)
+ else
+ for (var/mob/O in hearers(5, src.loc))
+ O.show_message("[user.name] forcefully slams the [src.name] with the [I.name]!" )
+ playsound(src.loc, 'sound/effects/Glasshit.ogg', 100, 1)
+ else
+ user << "This does nothing."
+ src.update_icon()
+
+
+/obj/machinery/newscaster/attack_paw(mob/user as mob)
+ user << "The newscaster controls are far too complicated for your tiny brain!"
+ return
+
+/obj/machinery/newscaster/proc/AttachPhoto(mob/user as mob)
+ if(photo)
+ photo.loc = src.loc
+ if(!issilicon(user))
+ user.put_in_inactive_hand(photo)
+ photo = null
+ if(istype(user.get_active_hand(), /obj/item/weapon/photo))
+ photo = user.get_active_hand()
+ user.drop_item()
+ photo.loc = src
+ if(istype(user,/mob/living/silicon/ai))
+ var/list/nametemp = list()
+ var/find
+ var/datum/picture/selection
+ var/mob/living/silicon/ai/tempAI = user
+ if(tempAI.aicamera.aipictures.len == 0)
+ usr << "No images saved"
+ return
+ for(var/datum/picture/t in tempAI.aicamera.aipictures)
+ nametemp += t.fields["name"]
+ find = input("Select image (numbered in order taken)") in nametemp
+ var/obj/item/weapon/photo/P = new/obj/item/weapon/photo()
+ for(var/datum/picture/q in tempAI.aicamera.aipictures)
+ if(q.fields["name"] == find)
+ selection = q
+ break // just in case some AI decides to take 10 thousand pictures in a round
+ P.icon = selection.fields["icon"]
+ P.img = selection.fields["img"]
+ P.desc = selection.fields["desc"]
+ photo = P
+ if(istype(user,/mob/living/silicon/robot))
+ var/list/nametemp = list()
+ var/find
+ var/datum/picture/selection
+ var/mob/living/silicon/robot/R = user
+ var/obj/item/device/camera/siliconcam/targetcam = null
+ if(R.connected_ai)
+ targetcam = R.connected_ai.aicamera
+ else
+ targetcam = R.aicamera
+ if(targetcam.aipictures.len == 0)
+ usr << "No images saved"
+ return
+ for(var/datum/picture/t in targetcam.aipictures)
+ nametemp += t.fields["name"]
+ find = input("Select image (numbered in order taken)") in nametemp
+ for(var/datum/picture/q in targetcam.aipictures)
+ if(q.fields["name"] == find)
+ selection = q
+ break
+ var/obj/item/weapon/photo/P = new/obj/item/weapon/photo()
+ P.construct(selection.fields["icon"], selection.fields["img"], selection.fields["desc"])
+ photo = P
+
+
+
+
+
+//########################################################################################################################
+//###################################### NEWSPAPER! ######################################################################
+//########################################################################################################################
+
+/obj/item/weapon/newspaper
+ name = "newspaper"
+ desc = "An issue of The Griffon, the newspaper circulating aboard Nanotrasen Space Stations."
+ icon = 'icons/obj/bureaucracy.dmi'
+ icon_state = "newspaper"
+ w_class = 2 //Let's make it fit in trashbags!
+ attack_verb = list("bapped")
+ var/screen = 0
+ var/pages = 0
+ var/curr_page = 0
+ var/list/datum/feed_channel/news_content = list()
+ var/datum/feed_message/important_message = null
+ var/scribble=""
+ var/scribble_page = null
+
+/*obj/item/weapon/newspaper/attack_hand(mob/user as mob)
+ ..()
+ world << "derp"*/
+
+obj/item/weapon/newspaper/attack_self(mob/user as mob)
+ if(ishuman(user))
+ var/mob/living/carbon/human/human_user = user
+ var/dat
+ src.pages = 0
+ switch(screen)
+ if(0) //Cover
+ dat+="The Griffon
"
+ dat+="Nanotrasen-standard newspaper, for use on Nanotrasen© Space Facilities
"
+ if(isemptylist(src.news_content))
+ if(src.important_message)
+ dat+="Contents:
**Important Security Announcement** \[page [src.pages+2]\]
"
+ else
+ dat+="Other than the title, the rest of the newspaper is unprinted..."
+ else
+ dat+="Contents:
"
+ for(var/datum/feed_channel/NP in src.news_content)
+ src.pages++
+ if(src.important_message)
+ dat+="**Important Security Announcement** \[page [src.pages+2]\]
"
+ var/temp_page=0
+ for(var/datum/feed_channel/NP in src.news_content)
+ temp_page++
+ dat+="[NP.channel_name] \[page [temp_page+1]\]
"
+ dat+="
"
+ if(scribble_page==curr_page)
+ dat+="
There is a small scribble near the end of this page... It reads: \"[src.scribble]\""
+ dat+= "
"
+ if(1) // X channel pages inbetween.
+ for(var/datum/feed_channel/NP in src.news_content)
+ src.pages++ //Let's get it right again.
+ var/datum/feed_channel/C = src.news_content[src.curr_page]
+ dat+="[C.channel_name] \[created by: [C.author]\]
"
+ if(C.censored)
+ dat+="This channel was deemed dangerous to the general welfare of the station and therefore marked with a D-Notice. Its contents were not transferred to the newspaper at the time of printing."
+ else
+ if(isemptylist(C.messages))
+ dat+="No Feed stories stem from this channel..."
+ else
+ dat+=""
+ var/i = 0
+ for(var/datum/feed_message/MESSAGE in C.messages)
+ i++
+ dat+="-[MESSAGE.body]
"
+ if(MESSAGE.img)
+ user << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
+ dat+="
"
+ dat+="\[Story by [MESSAGE.author]\]
"
+ dat+="
"
+ if(scribble_page==curr_page)
+ dat+="
There is a small scribble near the end of this page... It reads: \"[src.scribble]\""
+ dat+= "
"
+ if(2) //Last page
+ for(var/datum/feed_channel/NP in src.news_content)
+ src.pages++
+ if(src.important_message!=null)
+ dat+="Wanted Issue:
"
+ dat+="Criminal name: [important_message.author]
"
+ dat+="Description: [important_message.body]
"
+ dat+="Photo:: "
+ if(important_message.img)
+ user << browse_rsc(important_message.img, "tmp_photow.png")
+ dat+="
"
+ else
+ dat+="None"
+ else
+ dat+="Apart from some uninteresting Classified ads, there's nothing on this page..."
+ if(scribble_page==curr_page)
+ dat+="
There is a small scribble near the end of this page... It reads: \"[src.scribble]\""
+ dat+= "
"
+ else
+ dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
+
+ dat+="
[src.curr_page+1]
"
+ human_user << browse(dat, "window=newspaper_main;size=300x400")
+ onclose(human_user, "newspaper_main")
+ else
+ user << "The paper is full of intelligible symbols!"
+
+
+obj/item/weapon/newspaper/Topic(href, href_list)
+ var/mob/living/U = usr
+ ..()
+ if ((src in U.contents) || ( istype(loc, /turf) && in_range(src, U) ))
+ U.set_machine(src)
+ if(href_list["next_page"])
+ if(curr_page==src.pages+1)
+ return //Don't need that at all, but anyway.
+ if(src.curr_page == src.pages) //We're at the middle, get to the end
+ src.screen = 2
+ else
+ if(curr_page == 0) //We're at the start, get to the middle
+ src.screen=1
+ src.curr_page++
+ playsound(src.loc, "pageturn", 50, 1)
+
+ else if(href_list["prev_page"])
+ if(curr_page == 0)
+ return
+ if(curr_page == 1)
+ src.screen = 0
+
+ else
+ if(curr_page == src.pages+1) //we're at the end, let's go back to the middle.
+ src.screen = 1
+ src.curr_page--
+ playsound(src.loc, "pageturn", 50, 1)
+
+ if (istype(src.loc, /mob))
+ src.attack_self(src.loc)
+
+
+obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/pen))
+ if(src.scribble_page == src.curr_page)
+ user << "There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?"
+ else
+ var/s = strip_html( input(user, "Write something", "Newspaper", "") )
+ s = copytext(sanitize(s), 1, MAX_MESSAGE_LEN)
+ if (!s)
+ return
+ if (!in_range(src, usr) && src.loc != usr)
+ return
+ src.scribble_page = src.curr_page
+ src.scribble = s
+ src.attack_self(user)
+ return
+
+
+////////////////////////////////////helper procs
+
+
+/obj/machinery/newscaster/proc/scan_user(mob/living/user as mob)
+ if(istype(user,/mob/living/carbon/human)) //User is a human
+ var/mob/living/carbon/human/human_user = user
+ if(human_user.wear_id) //Newscaster scans you
+ if(istype(human_user.wear_id, /obj/item/device/pda) ) //autorecognition, woo!
+ var/obj/item/device/pda/P = human_user.wear_id
+ if(P.id)
+ src.scanned_user = "[P.id.registered_name] ([P.id.assignment])"
+ else
+ src.scanned_user = "Unknown"
+ else if(istype(human_user.wear_id, /obj/item/weapon/card/id) )
+ var/obj/item/weapon/card/id/ID = human_user.wear_id
+ src.scanned_user ="[ID.registered_name] ([ID.assignment])"
+ else
+ src.scanned_user ="Unknown"
+ else
+ src.scanned_user ="Unknown"
+ else
+ var/mob/living/silicon/ai_user = user
+ src.scanned_user = "[ai_user.name] ([ai_user.job])"
+
+
+/obj/machinery/newscaster/proc/print_paper()
+ feedback_inc("newscaster_newspapers_printed",1)
+ var/obj/item/weapon/newspaper/NEWSPAPER = new /obj/item/weapon/newspaper
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ NEWSPAPER.news_content += FC
+ if(news_network.wanted_issue)
+ NEWSPAPER.important_message = news_network.wanted_issue
+ NEWSPAPER.loc = get_turf(src)
+ src.paper_remaining--
+ return
+
+//Removed for now so these aren't even checked every tick. Left this here in-case Agouri needs it later.
+///obj/machinery/newscaster/process() //Was thinking of doing the icon update through process, but multiple iterations per second does not
+// return //bode well with a newscaster network of 10+ machines. Let's just return it, as it's added in the machines list.
+
+/obj/machinery/newscaster/proc/newsAlert(channel) //This isn't Agouri's work, for it is ugly and vile.
+ var/turf/T = get_turf(src) //Who the fuck uses spawn(600) anyway, jesus christ
+ if(channel)
+ for(var/mob/O in hearers(world.view-1, T))
+ O.show_message("[src.name] beeps, \"Breaking news from [channel]!\"",2)
+ src.alert = 1
+ src.update_icon()
+ spawn(300)
+ src.alert = 0
+ src.update_icon()
+ playsound(src.loc, 'sound/machines/twobeep.ogg', 75, 1)
+ else
+ for(var/mob/O in hearers(world.view-1, T))
+ O.show_message("[src.name] beeps, \"Attention! Wanted issue distributed!\"",2)
+ playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 75, 1)
return
\ No newline at end of file
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index c27b4893cc2..d0150d440d2 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -22,6 +22,8 @@
var/icon_old = null
var/pathweight = 1
+ flags = 0
+
/turf/New()
..()
for(var/atom/movable/AM as mob|obj in src)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index f078b822e3d..141c5047419 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -29,7 +29,7 @@ var/list/ai_list = list()
var/icon/holo_icon//Default is assigned when AI is created.
var/obj/item/device/pda/ai/aiPDA = null
var/obj/item/device/multitool/aiMulti = null
- var/obj/item/device/camera/ai_camera/aicamera = null
+ var/obj/item/device/camera/siliconcam/aicamera = null
//MALFUNCTION
var/datum/module_picker/malf_picker
@@ -86,7 +86,7 @@ var/list/ai_list = list()
aiPDA.name = name + " (" + aiPDA.ownjob + ")"
aiMulti = new(src)
- aicamera = new/obj/item/device/camera/ai_camera(src)
+ aicamera = new/obj/item/device/camera/siliconcam/ai_camera(src)
if (istype(loc, /turf))
verbs.Add(/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 54c38fcb787..5e561a38922 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -57,6 +57,9 @@
var/obj/item/weapon/tank/internal = null //Hatred. Used if a borg has a jetpack.
var/obj/item/robot_parts/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
+ var/obj/item/device/camera/siliconcam/aicamera = null //photography
+ var/toner = 0
+ var/tonermax = 40
@@ -112,6 +115,9 @@
mmi.brainmob.container = mmi
mmi.contents += mmi.brainmob
+ aicamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
+ toner = 40
+
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
@@ -579,6 +585,15 @@
else
usr << "Upgrade error!"
+ else if(istype(W, /obj/item/device/toner))
+ if(toner >= tonermax)
+ usr << "The toner level of [src] is at it's highest level possible"
+ else
+ toner = 40
+ usr.drop_item()
+ qdel(W)
+ usr << "You fill the toner level of [src] to it's max capacity"
+
else
if(W.force)
@@ -1103,4 +1118,4 @@
if(2) //New Module
connected_ai << "
NOTICE - Cyborg module change detected: [name] has loaded the [designation] module.
"
if(3) //New Name
- connected_ai << "
NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].
"
\ No newline at end of file
+ connected_ai << "
NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].
"
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index b002c91a8dc..1df8ee0aa83 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -188,7 +188,7 @@
var/datum/picture/selection
var/mob/living/silicon/ai/tempAI = usr
if(tempAI.aicamera.aipictures.len == 0)
- usr << "No images saved"
+ usr << "No images saved"
return
for(var/datum/picture/t in tempAI.aicamera.aipictures)
nametemp += t.fields["name"]
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 7a052ab2aa4..fb9637ca84f 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -4,6 +4,7 @@
* Camera Film
* Photos
* Photo Albums
+ * AI Photography
*/
/*
@@ -77,6 +78,11 @@
name = "photo[(n_name ? text("- '[n_name]'") : null)]"
add_fingerprint(usr)
+/obj/item/weapon/photo/proc/construct(var/inicon, var/inimg, var/indesc, var/inblueprints)
+ icon = inicon
+ img = inimg
+ desc = indesc
+ blueprints = inblueprints
/*
* Photo album
@@ -106,26 +112,53 @@
var/pictures_left = 10
var/on = 1
var/blueprints = 0 //are blueprints visible in the current photo being created?
- var/list/aipictures = list() //Allows for storage of pictures taken by AI, in a similar manner the datacore stores info
+ var/list/aipictures = list() //Allows for storage of pictures taken by AI, in a similar manner the datacore stores info. Keeping this here allows us to share some procs w/ regualar camera
-/obj/item/device/camera/ai_camera //camera AI can take pictures with
- name = "AI photo camera"
+/obj/item/device/camera/siliconcam
+ name = "silicon photo camera"
var/in_camera_mode = 0
- verb/picture()
- set category ="AI Commands"
- set name = "Take Image"
- set src in usr
+/obj/item/device/camera/siliconcam/ai_camera //camera AI can take pictures with
+ name = "AI photo camera"
- toggle_camera_mode()
+/obj/item/device/camera/siliconcam/ai_camera/verb/picture()
+ set category ="AI Commands"
+ set name = "Take Image"
+ set src in usr
- verb/viewpicture()
- set category ="AI Commands"
- set name = "View Images"
- set src in usr
+ toggle_camera_mode()
- viewpictures()
+/obj/item/device/camera/siliconcam/ai_camera/verb/viewpicture()
+ set category ="AI Commands"
+ set name = "View Images"
+ set src in usr
+
+ viewpictures()
+
+/obj/item/device/camera/siliconcam/robot_camera //camera cyborgs can take pictures with.. needs it's own because of verb CATEGORY >.>
+ name = "Cyborg photo camera"
+
+/obj/item/device/camera/siliconcam/robot_camera/verb/picture()
+ set category ="Robot Commands"
+ set name = "Take Image"
+ set src in usr
+
+ toggle_camera_mode()
+
+/obj/item/device/camera/siliconcam/robot_camera/verb/viewpicture()
+ set category ="Robot Commands"
+ set name = "View Images"
+ set src in usr
+
+ viewpictures(usr)
+
+/obj/item/device/camera/siliconcam/robot_camera/verb/borgprinting()
+ set category ="Robot Commands"
+ set name = "Print Image"
+ set src in usr
+
+ borgprint()
/obj/item/device/camera/attack(mob/living/carbon/human/M, mob/user)
@@ -232,10 +265,10 @@
temp.Blend("#000", ICON_OVERLAY)
temp.Blend(camera_get_icon(turfs, target), ICON_OVERLAY)
- if(!isAi)
+ if(!issilicon(user))
printpicture(user, temp, mobs, flag)
else
- aipicture(user, temp, mobs, blueprints)
+ aipicture(user, temp, mobs, isAi, blueprints)
@@ -258,7 +291,7 @@
blueprints = 0
-/obj/item/device/camera/proc/aipicture(mob/user, icon/temp, mobs) //instead of printing a picture like a regular camera would, we do this instead for the AI
+/obj/item/device/camera/proc/aipicture(mob/user, icon/temp, mobs, isAi) //instead of printing a picture like a regular camera would, we do this instead for the AI
var/icon/small_img = icon(temp)
var/icon/ic = icon('icons/obj/items.dmi',"photo")
@@ -275,7 +308,10 @@
injectblueprints = 1
blueprints = 0
- injectaialbum(icon, img, desc, pixel_x, pixel_y, injectblueprints)
+ if(isAi)
+ injectaialbum(icon, img, desc, pixel_x, pixel_y, injectblueprints)
+ else
+ injectmasteralbum(icon, img, desc, pixel_x, pixel_y, injectblueprints)
/datum/picture
@@ -288,7 +324,7 @@
for(var/datum/picture in src.aipictures)
numberer++
var/datum/picture/P = new()
- P.fields["name"] = "Image [numberer]"
+ P.fields["name"] = "Image [numberer] (taken by [src.loc.name])"
P.fields["icon"] = icon
P.fields["img"] = img
P.fields["desc"] = desc
@@ -297,33 +333,65 @@
P.fields["blueprints"] = blueprintsinject
aipictures += P
- usr << "Image recorded" //feedback to the AI player that the picture was taken
+ usr << "Image recorded" //feedback to the AI player that the picture was taken
+/obj/item/device/camera/proc/injectmasteralbum(var/icon, var/img, var/desc, var/pixel_x, var/pixel_y, var/blueprintsinject) //stores image information to a list similar to that of the datacore
+ var/numberer = 1
+ var/mob/living/silicon/robot/C = src.loc
+ if(C.connected_ai)
+ for(var/datum/picture in C.connected_ai.aicamera.aipictures)
+ numberer++
+ var/datum/picture/P = new()
+ P.fields["name"] = "Image [numberer] (taken by [src.loc.name])"
+ P.fields["icon"] = icon
+ P.fields["img"] = img
+ P.fields["desc"] = desc
+ P.fields["pixel_x"] = pixel_x
+ P.fields["pixel_y"] = pixel_y
+ P.fields["blueprints"] = blueprintsinject
-/obj/item/device/camera/ai_camera/proc/viewpictures() //AI proc for viewing pictures they have taken
+ C.connected_ai.aicamera.aipictures += P
+ usr << "Image recorded and saved to remote database" //feedback to the Cyborg player that the picture was taken
+ else
+ injectaialbum(icon, img, desc, pixel_x, pixel_y, blueprintsinject)
+
+obj/item/device/camera/siliconcam/proc/viewpichelper(var/obj/item/device/camera/siliconcam/targetloc)
var/list/nametemp = list()
var/find
var/datum/picture/selection
- if(src.aipictures.len == 0)
- usr << "No images saved"
+ if(targetloc.aipictures.len == 0)
+ usr << "No images saved"
return
- for(var/datum/picture/t in src.aipictures)
+ for(var/datum/picture/t in targetloc.aipictures)
nametemp += t.fields["name"]
find = input("Select image (numbered in order taken)") in nametemp
var/obj/item/weapon/photo/P = new/obj/item/weapon/photo()
- for(var/datum/picture/q in src.aipictures)
+ for(var/datum/picture/q in targetloc.aipictures)
if(q.fields["name"] == find)
selection = q
break // just in case some AI decides to take 10 thousand pictures in a round
- P.icon = selection.fields["icon"]
- P.img = selection.fields["img"]
- P.desc = selection.fields["desc"]
+ P.construct(selection.fields["icon"], selection.fields["img"], selection.fields["desc"])
P.pixel_x = selection.fields["pixel_x"]
P.pixel_y = selection.fields["pixel_y"]
P.show(usr)
usr << P.desc
- qdel(P) //so 10 thousdand pictures items are not left in memory should an AI take them and then view them all.
+ qdel(P) //so 10 thousand picture items are not left in memory should an AI take them and then view them all
+
+obj/item/device/camera/siliconcam/proc/viewpictures(user)
+ if(isrobot(user)) // Cyborg
+ var/mob/living/silicon/robot/C = src.loc
+ var/obj/item/device/camera/siliconcam/Cinfo
+ if(C.connected_ai)
+ Cinfo = C.connected_ai.aicamera
+ viewpichelper(Cinfo)
+ else
+ Cinfo = C.aicamera
+ viewpichelper(Cinfo)
+ else // AI
+ var/Ainfo = src
+ viewpichelper(Ainfo)
+
/obj/item/device/camera/afterattack(atom/target, mob/user, flag)
if(!on || !pictures_left || ismob(target.loc)) return
@@ -340,16 +408,47 @@
icon_state = "camera"
on = 1
-/obj/item/device/camera/ai_camera/proc/toggle_camera_mode()
+/obj/item/device/camera/siliconcam/proc/toggle_camera_mode()
if(in_camera_mode)
camera_mode_off()
else
camera_mode_on()
-/obj/item/device/camera/ai_camera/proc/camera_mode_off()
+/obj/item/device/camera/siliconcam/proc/camera_mode_off()
src.in_camera_mode = 0
usr << "Camera Mode deactivated"
-/obj/item/device/camera/ai_camera/proc/camera_mode_on()
+/obj/item/device/camera/siliconcam/proc/camera_mode_on()
src.in_camera_mode = 1
- usr << "Camera Mode activated"
\ No newline at end of file
+ usr << "Camera Mode activated"
+
+obj/item/device/camera/siliconcam/robot_camera/proc/borgprint()
+ var/list/nametemp = list()
+ var/find
+ var/datum/picture/selection
+ var/mob/living/silicon/robot/C = src.loc
+ var/obj/item/device/camera/siliconcam/targetcam = null
+ if(C.toner < 20)
+ usr << "Insufficent toner to print image."
+ return
+ if(C.connected_ai)
+ targetcam = C.connected_ai.aicamera
+ else
+ targetcam = C.aicamera
+ if(targetcam.aipictures.len == 0)
+ usr << "No images saved"
+ return
+ for(var/datum/picture/t in targetcam.aipictures)
+ nametemp += t.fields["name"]
+ find = input("Select image (numbered in order taken)") in nametemp
+ for(var/datum/picture/q in targetcam.aipictures)
+ if(q.fields["name"] == find)
+ selection = q
+ break
+ var/obj/item/weapon/photo/p = new /obj/item/weapon/photo(C.loc)
+ p.construct(selection.fields["icon"], selection.fields["img"], selection.fields["desc"], selection.fields["blueprints"])
+ p.pixel_x = rand(-10, 10)
+ p.pixel_y = rand(-10, 10)
+ C.toner -= 20 //Cyborgs are very ineffeicient at printing an image
+ visible_message("[C.name] spits out a photograph from a narrow slot on it's chassis.")
+ usr << "You print a photograph."
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index a0f1b088155..cf33cbb7529 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -645,6 +645,7 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime)
D = new type(0, null)
if(!D)
return
+ replicator_cooldown(50)
var/list/data = list("viruses"=list(D))
var/name = sanitize(input(usr,"Name:","Name the culture",D.name))
if(!name || name == " ") name = D.name
@@ -652,7 +653,6 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime)
B.desc = "A small bottle. Contains [D.agent] culture in synthblood medium."
B.reagents.add_reagent("blood",20,data)
src.updateUsrDialog()
- replicator_cooldown(50)
else
src.temp_html = "The replicator is not ready yet."
src.updateUsrDialog()
diff --git a/html/changelog.html b/html/changelog.html
index 5cdc20127fd..87fb69cc6e2 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -104,6 +104,7 @@ should be listed in the changelog upon commit tho. Thanks. -->
+
3 April 2014
Ikarrus updated: