From 0e0cc0af50face859b8da7d77a970fc6390063cb Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 27 Aug 2015 15:33:33 +0200 Subject: [PATCH 1/2] Ghost interaction update, voice changer fix, man up global confirmation --- code/game/machinery/atmoalter/canister.dm | 14 +- code/game/machinery/atmoalter/pump.dm | 2 +- code/game/machinery/atmoalter/scrubber.dm | 2 +- code/game/machinery/firealarm.dm | 52 +- code/game/machinery/newscaster.dm | 490 +++++++++--------- .../objects/items/devices/radio/intercom.dm | 8 +- .../game/objects/items/devices/radio/radio.dm | 9 +- code/modules/admin/admin_verbs.dm | 13 +- code/modules/mob/living/carbon/human/say.dm | 10 +- code/modules/nano/interaction/base.dm | 5 + 10 files changed, 293 insertions(+), 312 deletions(-) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 702f7512535..644420fc3c1 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -74,6 +74,7 @@ var/datum/canister_icons/canister_icon_container = new() var/temperature_resistance = 1000 + T0C volume = 1000 use_power = 0 + interact_offline = 1 var/release_log = "" var/busy = 0 var/update_flag = 0 @@ -424,16 +425,9 @@ update_flag possibledecals = new /list(3) /obj/machinery/portable_atmospherics/canister/Topic(href, href_list) - - //Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict. // yeah but without SOME sort of Topic check any dick can mess with them via exploits as he pleases -walter0o - if (!istype(src.loc, /turf)) - return 0 - - if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) // exploit protection -walter0o - usr << browse(null, "window=canister") - onclose(usr, "canister") - return - + if(..()) + return 1 + if (href_list["choice"] == "menu") menu = text2num(href_list["mode_target"]) diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm index e9fb01b034c..23dca91dd51 100644 --- a/code/game/machinery/atmoalter/pump.dm +++ b/code/game/machinery/atmoalter/pump.dm @@ -99,7 +99,7 @@ src.add_hiddenprint(user) return src.attack_hand(user) -/obj/machinery/portable_atmospherics/pump/attack_ghost(var/mob/user) +/obj/machinery/portable_atmospherics/pump/attack_ghost(var/mob/user as mob) return src.attack_hand(user) /obj/machinery/portable_atmospherics/pump/attack_hand(var/mob/user as mob) diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index b6dabbdec32..5ab92bd3088 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -109,7 +109,7 @@ src.add_hiddenprint(user) return src.attack_hand(user) -/obj/machinery/portable_atmospherics/scrubber/attack_ghost(var/mob/user) +/obj/machinery/portable_atmospherics/scrubber/attack_ghost(var/mob/user as mob) return src.attack_hand(user) /obj/machinery/portable_atmospherics/scrubber/attack_hand(var/mob/user as mob) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 2c03a7a92e8..75acd99fb58 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -53,12 +53,15 @@ FIRE ALARM if(src.detecting) if(temperature > T0C+200) src.alarm() // added check of detector status here - return - + return + /obj/machinery/firealarm/attack_ai(mob/user as mob) src.add_hiddenprint(user) return src.attack_hand(user) +/obj/machinery/firealarm/attack_ghost(mob/user as mob) + return src.attack_hand(user) + /obj/machinery/firealarm/bullet_act(BLAH) return src.alarm() @@ -174,7 +177,7 @@ FIRE ALARM var/area/A = src.loc var/d1 var/d2 - if (istype(user, /mob/living/carbon/human) || istype(user, /mob/living/silicon)) + if (ishuman(user) || issilicon(user) || isobserver(user)) A = A.loc if (A.fire) @@ -208,34 +211,27 @@ FIRE ALARM return /obj/machinery/firealarm/Topic(href, href_list) - ..() - if (usr.stat || stat & (BROKEN|NOPOWER)) - return - + if(..()) + return 1 + if (buildstage != 2) - return + return 1 - 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["reset"]) - src.reset() - else if (href_list["alarm"]) - src.alarm() - else if (href_list["time"]) - src.timing = text2num(href_list["time"]) - last_process = world.timeofday - processing_objects.Add(src) - else if (href_list["tp"]) - var/tp = text2num(href_list["tp"]) - src.time += tp - src.time = min(max(round(src.time), 0), 120) + if (href_list["reset"]) + src.reset() + else if (href_list["alarm"]) + src.alarm() + else if (href_list["time"]) + src.timing = text2num(href_list["time"]) + last_process = world.timeofday + processing_objects.Add(src) + else if (href_list["tp"]) + var/tp = text2num(href_list["tp"]) + src.time += tp + src.time = min(max(round(src.time), 0), 120) - src.updateUsrDialog() - - src.add_fingerprint(usr) - else - usr << browse(null, "window=firealarm") - return + src.updateUsrDialog() + src.add_fingerprint(usr) return /obj/machinery/firealarm/proc/reset() diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index eef7223d15b..43d4363a997 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -183,9 +183,6 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co if(!src.ispowered || src.isbroken) return - if(!user.IsAdvancedToolUser()) - return 0 - if(istype(user, /mob/living/carbon/human) || istype(user,/mob/living/silicon) ) var/mob/living/human_or_robot_user = user var/dat @@ -444,273 +441,272 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co /obj/machinery/newscaster/Topic(href, href_list) if(..()) return 1 - 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 = sanitizeSQL(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() + + usr.set_machine(src) + if(href_list["set_channel_name"]) + src.channel_name = sanitizeSQL(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["set_channel_lock"]) + src.c_locked = !src.c_locked + src.updateUsrDialog() + //src.update_icon() - else if(href_list["submit_new_channel"]) - //var/list/existing_channels = list() //OBSOLETE - 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 + else if(href_list["submit_new_channel"]) + //var/list/existing_channels = list() //OBSOLETE + 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") + var/datum/feed_channel/newChannel = new /datum/feed_channel + newChannel.channel_name = src.channel_name + newChannel.author = src.scanned_user + newChannel.locked = c_locked + feedback_inc("newscaster_channels",1) + /*for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) //Let's add the new channel in all casters. + NEWSCASTER.channel_list += newChannel*/ //Now that it is sane, get it into the list. -OBSOLETE + news_network.network_channels += newChannel //Adding channel to the global network + 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 = strip_html_simple(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 + var/datum/feed_message/newMsg = new /datum/feed_message + newMsg.author = src.scanned_user + newMsg.body = src.msg + if(photo) + newMsg.img = photo.img + feedback_inc("newscaster_stories",1) + var/announcement = "" for(var/datum/feed_channel/FC in news_network.network_channels) if(FC.channel_name == src.channel_name) - check = 1 + FC.messages += newMsg //Adding message to the network's appropriate feed_channel + announcement = FC.announce_news() 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") - var/datum/feed_channel/newChannel = new /datum/feed_channel - newChannel.channel_name = src.channel_name - newChannel.author = src.scanned_user - newChannel.locked = c_locked - feedback_inc("newscaster_channels",1) - /*for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) //Let's add the new channel in all casters. - NEWSCASTER.channel_list += newChannel*/ //Now that it is sane, get it into the list. -OBSOLETE - news_network.network_channels += newChannel //Adding channel to the global network - src.screen=5 - src.updateUsrDialog() - //src.update_icon() + src.screen=4 + for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) + NEWSCASTER.newsAlert(announcement) - 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 = strip_html_simple(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels ) - src.updateUsrDialog() + 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["create_channel"]) + src.screen=2 + src.updateUsrDialog() - else if(href_list["set_attachment"]) - AttachPhoto(usr) - src.updateUsrDialog() + else if(href_list["create_feed_story"]) + src.screen=3 + 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 - var/datum/feed_message/newMsg = new /datum/feed_message - newMsg.author = src.scanned_user - newMsg.body = src.msg - if(photo) - newMsg.img = photo.img - feedback_inc("newscaster_stories",1) - var/announcement = "" - for(var/datum/feed_channel/FC in news_network.network_channels) - if(FC.channel_name == src.channel_name) - FC.messages += newMsg //Adding message to the network's appropriate feed_channel - announcement = FC.announce_news() - break - src.screen=4 - for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) - NEWSCASTER.newsAlert(announcement) + 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() - src.updateUsrDialog() + else if(href_list["menu_censor_story"]) + src.screen=10 + src.updateUsrDialog() - else if(href_list["create_channel"]) - src.screen=2 - src.updateUsrDialog() + else if(href_list["menu_censor_channel"]) + src.screen=11 + src.updateUsrDialog() - else if(href_list["create_feed_story"]) - src.screen=3 - src.updateUsrDialog() + else if(href_list["menu_wanted"]) + var/already_wanted = 0 + if(news_network.wanted_issue) + already_wanted = 1 - 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() + 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["menu_censor_story"]) - src.screen=10 - 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["menu_censor_channel"]) - src.screen=11 - 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["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") + 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") - news_network.wanted_issue = null - for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) - NEWSCASTER.update_icon() - src.screen=17 - src.updateUsrDialog() + 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 - 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() + 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["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["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.img != null) - MSG.backup_img = MSG.img - MSG.img = null - else - MSG.img = MSG.backup_img - if(MSG.body != "\[REDACTED\]") - MSG.backup_body = MSG.body - MSG.body = "\[REDACTED\]" - else - MSG.body = MSG.backup_body - 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["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["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["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["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.img != null) + MSG.backup_img = MSG.img + MSG.img = null + else + MSG.img = MSG.backup_img + if(MSG.body != "\[REDACTED\]") + MSG.backup_body = MSG.body + MSG.body = "\[REDACTED\]" + else + MSG.body = MSG.backup_body + src.updateUsrDialog() - else if(href_list["view"]) - src.screen=1 - 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["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["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["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["view"]) + src.screen=1 + 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["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["refresh"]) - 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/living/user as mob, params) if(istype(I, /obj/item/weapon/wrench)) @@ -746,10 +742,6 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co user << "This does nothing." src.update_icon() -/obj/machinery/newscaster/attack_ai(mob/user as mob) - return src.attack_hand(user) //or maybe it'll have some special functions? No idea. - - /obj/machinery/newscaster/proc/AttachPhoto(mob/user as mob) if(photo) if(!issilicon(user)) @@ -794,11 +786,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co 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) +/obj/item/weapon/newspaper/attack_self(mob/user as mob) if(ishuman(user)) var/mob/living/carbon/human/human_user = user var/dat diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 3cbcde23f4a..b6bb39bd32b 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -37,12 +37,16 @@ /obj/item/device/radio/intercom/attack_ai(mob/user as mob) add_hiddenprint(user) add_fingerprint(user) - spawn (0) + spawn(0) + attack_self(user) + +/obj/item/device/radio/intercom/attack_ghost(mob/user as mob) + spawn(0) attack_self(user) /obj/item/device/radio/intercom/attack_hand(mob/user as mob) add_fingerprint(user) - spawn (0) + spawn(0) attack_self(user) /obj/item/device/radio/intercom/receive_range(freq, level) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 62498009f0b..cf26aeca7c0 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -122,14 +122,9 @@ listening = !listening && !(wires.IsIndexCut(WIRE_RECEIVE) || wires.IsIndexCut(WIRE_SIGNAL)) /obj/item/device/radio/Topic(href, href_list) - //..() - if (usr.stat || !on) - return + if(..()) + return 1 - if (!(issilicon(usr) || (usr.contents.Find(src) || ( in_range(src, usr) && istype(loc, /turf) )))) - usr << browse(null, "window=radio") - return - usr.set_machine(src) if (href_list["track"]) var/mob/target = locate(href_list["track"]) var/mob/living/silicon/ai/A = locate(href_list["track2"]) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 488eb2c50c5..b41dece52d7 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -846,10 +846,13 @@ var/list/admin_verbs_mentor = list( set category = "Admin" set name = "Man Up Global" set desc = "Tells everyone to man up and deal with it." + + var/confirm = alert("Are you sure you want to send the global message?", "Confirm Man Up Global", "Yes", "No") - for (var/mob/T as mob in mob_list) - T << "
Man up.
Deal with it.

Move on.

" - T << 'sound/voice/ManUp1.ogg' + if(confirm == "Yes") + for (var/mob/T as mob in mob_list) + T << "
Man up.
Deal with it.

Move on.

" + T << 'sound/voice/ManUp1.ogg' - log_admin("[key_name(usr)] told everyone to man up and deal with it.") - message_admins("\blue [key_name_admin(usr)] told everyone to man up and deal with it.", 1) + log_admin("[key_name(usr)] told everyone to man up and deal with it.") + message_admins("\blue [key_name_admin(usr)] told everyone to man up and deal with it.", 1) diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 0a38453c5fd..729ce6c8cae 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -27,7 +27,7 @@ return emote(copytext(message,2)) if(name != GetVoice()) - alt_name = "(as [get_id_name("Unknown")])" + alt_name = " (as [get_id_name("Unknown")])" //parse the radio code and consume it if (message_mode) @@ -214,17 +214,13 @@ continue var/obj/item/voice_changer/changer = locate() in gear if(changer && changer.active && changer.voice) - return changer + return changer.voice return 0 /mob/living/carbon/human/GetVoice() - - var/voice_sub var/has_changer = HasVoiceChanger() if(has_changer) - voice_sub = has_changer - if(voice_sub) - return voice_sub + return has_changer if(mind && mind.changeling && mind.changeling.mimicing) return mind.changeling.mimicing if(GetSpecialVoice()) diff --git a/code/modules/nano/interaction/base.dm b/code/modules/nano/interaction/base.dm index 85ac56eeedc..e70b4423705 100644 --- a/code/modules/nano/interaction/base.dm +++ b/code/modules/nano/interaction/base.dm @@ -17,6 +17,11 @@ else if (restrained() || lying || stat || stunned || weakened) return STATUS_UPDATE // update only (orange visibility) return STATUS_INTERACTIVE + +/mob/dead/observer/shared_nano_interaction() + if(check_rights(R_ADMIN, 0, src)) + return STATUS_INTERACTIVE // Admins are more equal + return STATUS_UPDATE // Ghosts can view updates /mob/living/silicon/ai/shared_nano_interaction() if(lacks_power()) From 3d970aba1f1e9643f1900cd58f218753c8c5c71c Mon Sep 17 00:00:00 2001 From: Markolie Date: Thu, 27 Aug 2015 15:54:04 +0200 Subject: [PATCH 2/2] Fixes invisible alien leap --- .../carbon/alien/humanoid/caste/hunter.dm | 1 + .../living/carbon/alien/humanoid/humanoid.dm | 21 +++++++++++++++++- .../carbon/alien/humanoid/update_icons.dm | 16 ++++++++----- code/modules/mob/living/living.dm | 3 ++- icons/mob/alienleap.dmi | Bin 3985 -> 4035 bytes 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index 018c37e4ad6..52fd9ad29fc 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -110,6 +110,7 @@ if(leaping) leaping = 0 + update_icons() update_canmove() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 7d8ab9932df..b88004e4a2d 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -7,11 +7,14 @@ var/obj/item/weapon/r_store = null var/obj/item/weapon/l_store = null var/caste = "" + var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files. var/next_attack = 0 var/pounce_cooldown = 0 var/pounce_cooldown_time = 30 update_icon = 1 var/leap_on_click = 0 + var/custom_pixel_x_offset = 0 //for admin fuckery. + var/custom_pixel_y_offset = 0 //This is fine right now, if we're adding organ specific damage this needs to be updated /mob/living/carbon/alien/humanoid/New() @@ -336,4 +339,20 @@ In all, this is a lot like the monkey code. /N /mob/living/carbon/alien/humanoid/canBeHandcuffed() - return 1 \ No newline at end of file + return 1 + +/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0) + if(leaping) + return -32 + else if(custom_pixel_y_offset) + return custom_pixel_y_offset + else + return initial(pixel_y) + +/mob/living/carbon/alien/humanoid/get_standard_pixel_x_offset(lying = 0) + if(leaping) + return -32 + else if(custom_pixel_x_offset) + return custom_pixel_x_offset + else + return initial(pixel_x) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index 4c24b06bbe0..740c3e5ce25 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -41,14 +41,20 @@ icon_state = "alien[caste]_s" if(leaping) - icon = 'icons/mob/alienleap.dmi' + if(alt_icon == initial(alt_icon)) + var/old_icon = icon + icon = alt_icon + alt_icon = old_icon icon_state = "alien[caste]_leap" pixel_x = -32 pixel_y = -32 - else if(icon == 'icons/mob/alienleap.dmi' && pixel_x == -32 && pixel_y == -32) - icon = initial(icon)// ^ this looks odd, but in theory it will prevent the icon and pixel_xy from being reset unless it needs to be - pixel_x = initial(pixel_x) - pixel_y = initial(pixel_y) + else + if(alt_icon != initial(alt_icon)) + var/old_icon = icon + icon = alt_icon + alt_icon = old_icon + pixel_x = get_standard_pixel_x_offset(lying) + pixel_y = get_standard_pixel_y_offset(lying) /mob/living/carbon/alien/humanoid/regenerate_icons() ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index fa834fa581b..416dc1626cd 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -936,4 +936,5 @@ return initial(pixel_y) /mob/living/proc/spawn_dust() - new /obj/effect/decal/cleanable/ash(loc) \ No newline at end of file + new /obj/effect/decal/cleanable/ash(loc) + \ No newline at end of file diff --git a/icons/mob/alienleap.dmi b/icons/mob/alienleap.dmi index 3adf4ff7597a816d781532c52435ca8324a7fca2..da092d4b9bdf2993bf1295efcd5614abc5da8b3b 100644 GIT binary patch delta 3665 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 Wy&5n$Ry_IYF&P_}->%bhj{6TNt9=Xr