Cleans up remnant traitor cyborg code and AI hacking.

This commit is contained in:
AnturK
2018-02-15 06:01:15 +01:00
committed by CitadelStationBot
parent 95582c597b
commit 10a40524ab
11 changed files with 188 additions and 68 deletions
+1 -1
View File
@@ -238,7 +238,7 @@ Turf and target are separate in case you want to teleport some distance from a t
continue
if(R.stat == DEAD)
continue
if(R.emagged || R.scrambledcodes || R.syndicate)
if(R.emagged || R.scrambledcodes)
continue
. += R
+80
View File
@@ -1,3 +1,4 @@
<<<<<<< HEAD
/obj/machinery/computer/upload
@@ -75,4 +76,83 @@
return 0
if(B.scrambledcodes || B.emagged)
return 0
=======
/obj/machinery/computer/upload
var/mob/living/silicon/current = null //The target of future law uploads
icon_screen = "command"
/obj/machinery/computer/upload/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/aiModule))
var/obj/item/aiModule/M = O
if(src.stat & (NOPOWER|BROKEN|MAINT))
return
if(!current)
to_chat(user, "<span class='caution'>You haven't selected anything to transmit laws to!</span>")
return
if(!can_upload_to(current))
to_chat(user, "<span class='caution'>Upload failed!</span> Check to make sure [current.name] is functioning properly.")
current = null
return
var/turf/currentloc = get_turf(current)
if(currentloc && user.z != currentloc.z)
to_chat(user, "<span class='caution'>Upload failed!</span> Unable to establish a connection to [current.name]. You're too far away!")
current = null
return
M.install(current.laws, user)
else
return ..()
/obj/machinery/computer/upload/proc/can_upload_to(mob/living/silicon/S)
if(S.stat == DEAD)
return 0
return 1
/obj/machinery/computer/upload/ai
name = "\improper AI upload console"
desc = "Used to upload laws to the AI."
circuit = /obj/item/circuitboard/computer/aiupload
/obj/machinery/computer/upload/ai/attack_hand(mob/user)
if(..())
return
src.current = select_active_ai(user)
if (!src.current)
to_chat(user, "<span class='caution'>No active AIs detected!</span>")
else
to_chat(user, "[src.current.name] selected for law changes.")
/obj/machinery/computer/upload/ai/can_upload_to(mob/living/silicon/ai/A)
if(!A || !isAI(A))
return 0
if(A.control_disabled)
return 0
return ..()
/obj/machinery/computer/upload/borg
name = "cyborg upload console"
desc = "Used to upload laws to Cyborgs."
circuit = /obj/item/circuitboard/computer/borgupload
/obj/machinery/computer/upload/borg/attack_hand(mob/user)
if(..())
return
src.current = select_active_free_borg(user)
if(!src.current)
to_chat(user, "<span class='caution'>No active unslaved cyborgs detected!</span>")
else
to_chat(user, "[src.current.name] selected for law changes.")
/obj/machinery/computer/upload/borg/can_upload_to(mob/living/silicon/robot/B)
if(!B || !iscyborg(B))
return 0
if(B.scrambledcodes || B.emagged)
return 0
>>>>>>> 7a7798f... Cleans up remnant traitor cyborg code and AI hacking. (#35586)
return ..()
+17 -24
View File
@@ -1,6 +1,3 @@
/obj/machinery/computer/robotics
name = "robotics control console"
desc = "Used to remotely lockdown or detonate linked Cyborgs and Drones."
@@ -61,11 +58,14 @@
dat += " Slaved to [R.connected_ai.name] |"
else
dat += " Independent from AI |"
if(issilicon(user) || IsAdminGhost(user))
if(is_servant_of_ratvar(user) && user != R)
if(issilicon(user) && user != R)
var/mob/living/silicon/S = user
if(is_servant_of_ratvar(S))
dat += "<A href='?src=[REF(src)];convert=[REF(R)]'>(<font color=#BE8700><i>Convert</i></font>)</A> "
else if(((issilicon(user) && is_special_character(user)) || IsAdminGhost(user)) && !R.emagged && (user != R || R.syndicate))
else if(S.hack_software && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
else if(IsAdminGhost(user) && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
dat += "<A href='?src=[REF(src)];stopbot=[REF(R)]'>(<font color=green><i>[R.canmove ? "Lockdown" : "Release"]</i></font>)</A> "
dat += "<A href='?src=[REF(src)];killbot=[REF(R)]'>(<font color=red><i>Destroy</i></font>)</A>"
dat += "<BR>"
@@ -107,18 +107,12 @@
if(can_control(usr, R))
var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
if(R.syndicate && R.emagged)
to_chat(R, "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered.")
if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
R.ResetSecurityCodes()
else
var/turf/T = get_turf(R)
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] detonated [key_name(R, R.client)][ADMIN_JMP(T)]!</span>")
log_game("\<span class='notice'>[key_name(usr)] detonated [key_name(R)]!</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
R.self_destruct()
var/turf/T = get_turf(R)
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] detonated [key_name(R, R.client)][ADMIN_JMP(T)]!</span>")
log_game("\<span class='notice'>[key_name(usr)] detonated [key_name(R)]!</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
R.self_destruct()
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
@@ -139,19 +133,18 @@
to_chat(usr, "<span class='danger'>Access Denied.</span>")
else if (href_list["magbot"])
if((issilicon(usr) && is_special_character(usr)) || IsAdminGhost(usr))
var/mob/living/silicon/S = usr
if((istype(S) && S.hack_software) || IsAdminGhost(usr))
var/mob/living/silicon/robot/R = locate(href_list["magbot"]) in GLOB.silicon_mobs
if(istype(R) && !R.emagged && ((R.syndicate && R == usr) || R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R))
if(istype(R) && !R.emagged && (R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R))
log_game("[key_name(usr)] emagged [R.name] using robotic console!")
message_admins("[key_name_admin(usr)] emagged cyborg [key_name_admin(R)] using robotic console!")
R.SetEmagged(1)
if(is_special_character(R))
R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes
else if(href_list["convert"])
if(issilicon(usr) && is_special_character(usr))
if(isAI(usr) && is_servant_of_ratvar(usr))
var/mob/living/silicon/robot/R = locate(href_list["convert"]) in GLOB.silicon_mobs
if(istype(R) && !is_servant_of_ratvar(R) && is_servant_of_ratvar(usr) && R.connected_ai == usr)
if(istype(R) && !is_servant_of_ratvar(R) && R.connected_ai == usr)
log_game("[key_name(usr)] converted [R.name] using robotic console!")
message_admins("[key_name_admin(usr)] converted cyborg [key_name_admin(R)] using robotic console!")
add_servant_of_ratvar(R)
@@ -118,7 +118,8 @@
else
for(var/n = ++i; n <= optioncount; n++)
dat += "<dd><font color='blue'>&#09;[n]. ---------------</font><br></dd>"
if(issilicon(usr) && is_special_character(usr))
var/mob/living/silicon/S = usr
if(istype(S) && S.hack_software)
//Malf/Traitor AIs can bruteforce into the system to gain the Key.
dat += "<dd><A href='?src=[REF(src)];hack=1'><i><font color='Red'>*&@#. Bruteforce Key</font></i></font></a><br></dd>"
else
@@ -338,7 +339,8 @@
//Hack the Console to get the password
if (href_list["hack"])
if(issilicon(usr) && is_special_character(usr))
var/mob/living/silicon/S = usr
if(istype(S) && S.hack_software)
hacking = TRUE
screen = 2
//Time it takes to bruteforce is dependant on the password length.
@@ -221,6 +221,18 @@
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
owner.current.grant_language(/datum/language/codespeak)
/datum/antagonist/traitor/AI/apply_innate_effects(mob/living/mob_override)
. = ..()
var/mob/living/silicon/ai/A = mob_override || owner.current
if(istype(A))
A.hack_software = TRUE
/datum/antagonist/traitor/AI/remove_innate_effects(mob/living/mob_override)
. = ..()
var/mob/living/silicon/ai/A = mob_override || owner.current
if(istype(A))
A.hack_software = FALSE
/datum/antagonist/traitor/human/finalize_traitor()
..()
if(should_equip)
@@ -1,3 +1,4 @@
<<<<<<< HEAD
/mob/living/silicon/robot/verb/cmd_show_laws()
set category = "Robot Commands"
set name = "Show Laws"
@@ -73,4 +74,74 @@
temp = master.supplied[index]
if (length(temp) > 0)
laws.supplied[index] = temp
=======
/mob/living/silicon/robot/verb/cmd_show_laws()
set category = "Robot Commands"
set name = "Show Laws"
if(usr.stat == DEAD)
return //won't work if dead
show_laws()
/mob/living/silicon/robot/show_laws(everyone = 0)
laws_sanity_check()
var/who
if (everyone)
who = world
else
who = src
if(lawupdate)
if (connected_ai)
if(connected_ai.stat || connected_ai.control_disabled)
to_chat(src, "<b>AI signal lost, unable to sync laws.</b>")
else
lawsync()
to_chat(src, "<b>Laws synced with AI, be sure to note any changes.</b>")
else
to_chat(src, "<b>No AI selected to sync laws with, disabling lawsync protocol.</b>")
lawupdate = 0
to_chat(who, "<b>Obey these laws:</b>")
laws.show_laws(who)
if (shell) //AI shell
to_chat(who, "<b>Remember, you are an AI remotely controlling your shell, other AIs can be ignored.</b>")
else if (connected_ai)
to_chat(who, "<b>Remember, [connected_ai.name] is your master, other AIs can be ignored.</b>")
else if (emagged)
to_chat(who, "<b>Remember, you are not required to listen to the AI.</b>")
else
to_chat(who, "<b>Remember, you are not bound to any AI, you are not required to listen to them.</b>")
/mob/living/silicon/robot/proc/lawsync()
laws_sanity_check()
var/datum/ai_laws/master = connected_ai ? connected_ai.laws : null
var/temp
if (master)
laws.ion.len = master.ion.len
for (var/index = 1, index <= master.ion.len, index++)
temp = master.ion[index]
if (length(temp) > 0)
laws.ion[index] = temp
if(master.zeroth_borg) //If the AI has a defined law zero specifically for its borgs, give it that one, otherwise give it the same one. --NEO
temp = master.zeroth_borg
else
temp = master.zeroth
laws.zeroth = temp
laws.inherent.len = master.inherent.len
for (var/index = 1, index <= master.inherent.len, index++)
temp = master.inherent[index]
if (length(temp) > 0)
laws.inherent[index] = temp
laws.supplied.len = master.supplied.len
for (var/index = 1, index <= master.supplied.len, index++)
temp = master.supplied[index]
if (length(temp) > 0)
laws.supplied[index] = temp
>>>>>>> 7a7798f... Cleans up remnant traitor cyborg code and AI hacking. (#35586)
return
@@ -35,21 +35,6 @@
update_cell_hud_icon()
if(syndicate)
if(SSticker.mode.name == "traitor")
for(var/datum/mind/tra in SSticker.mode.traitors)
if(tra.current)
var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor") //no traitor sprite in that dmi!
src.client.images += I
if(connected_ai)
connected_ai.connected_robots -= src
connected_ai = null
if(mind)
if(!mind.special_role)
mind.special_role = ROLE_TRAITOR
mind.add_antag_datum(/datum/antagonist/auto_custom) // ????
/mob/living/silicon/robot/update_health_hud()
if(!client || !hud_used)
return
@@ -660,18 +660,6 @@
// to have to check if every camera is null or not before doing anything, to prevent runtime errors.
// I could change the network to null but I don't know what would happen, and it seems too hacky for me.
/mob/living/silicon/robot/proc/ResetSecurityCodes()
set category = "Robot Commands"
set name = "Reset Identity Codes"
set desc = "Scrambles your security and identification codes and resets your current buffers. Unlocks you and permanently severs you from your AI and the robotics console and will deactivate your camera system."
var/mob/living/silicon/robot/R = src
if(R)
R.UnlinkSelf()
to_chat(R, "Buffers flushed and reset. Camera system shutdown. All systems operational.")
src.verbs -= /mob/living/silicon/robot/proc/ResetSecurityCodes
/mob/living/silicon/robot/mode()
set name = "Activate Held Object"
set category = "IC"
@@ -113,11 +113,6 @@
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they serve only Ratvar.")
return
if(syndicate)
to_chat(src, "<span class='danger'>ALERT: Foreign software execution prevented.</span>")
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they were a syndicate cyborg.")
return
if(connected_ai && connected_ai.mind && connected_ai.mind.has_antag_datum(/datum/antagonist/traitor))
to_chat(src, "<span class='danger'>ALERT: Foreign software execution prevented.</span>")
to_chat(connected_ai, "<span class='danger'>ALERT: Cyborg unit \[[src]] successfully defended against subversion.</span>")
+2 -1
View File
@@ -11,7 +11,6 @@
weather_immunities = list("ash")
possible_a_intents = list(INTENT_HELP, INTENT_HARM)
var/syndicate = 0
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
var/last_lawchange_announce = 0
var/list/alarms_to_show = list()
@@ -39,6 +38,8 @@
var/obj/machinery/camera/builtInCamera = null
var/updating = FALSE //portable camera camerachunk update
var/hack_software = FALSE //Will be able to use hacking actions
/mob/living/silicon/Initialize()
. = ..()
GLOB.silicon_mobs += src
+1 -8
View File
@@ -336,14 +336,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
return FALSE
if(issilicon(M))
if(iscyborg(M)) //For cyborgs, returns 1 if the cyborg has a law 0 and special_role. Returns 0 if the borg is merely slaved to an AI traitor.
var/mob/living/silicon/robot/R = M
if(R.mind && R.mind.special_role)
if(R.laws && R.laws.zeroth && R.syndicate)
if(R.connected_ai)
if(is_special_character(R.connected_ai) && R.connected_ai.laws && (R.connected_ai.laws.zeroth_borg == R.laws.zeroth || R.connected_ai.laws.zeroth == R.laws.zeroth))
return 0 //AI is the real traitor here, so the borg itself is not a traitor
return TRUE//Slaved but also a traitor
return TRUE //Unslaved, traitor
return FALSE
else if(isAI(M))
var/mob/living/silicon/ai/A = M
if(A.laws && A.laws.zeroth && A.mind && A.mind.special_role)