Revival of "Allows AIs to deploy to borgs" by Shadowlight213 (#25184)

The AI may now deploy to cyborgs prepared as AI shells. The module to do this may be research in the exosuit fabricator. Simply slot the module into a completed cyborg frame as with an MMI, or into a playerless (with no ckey) cyborg.
This commit is contained in:
GunHog
2017-03-24 19:42:48 -05:00
committed by Leo
parent aab6a58e05
commit ac4d69254b
24 changed files with 343 additions and 36 deletions

View File

@@ -34,3 +34,9 @@
#define FLOOR_BOT 4 // Floorbots
#define CLEAN_BOT 8 // Cleanbots
#define MED_BOT 16 // Medibots
//AI notification defines
#define NEW_BORG 1
#define NEW_MODULE 2
#define RENAME 3
#define AI_SHELL 4

View File

@@ -232,7 +232,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
/proc/active_free_borgs()
. = list()
for(var/mob/living/silicon/robot/R in living_mob_list)
if(R.connected_ai)
if(R.connected_ai || R.shell)
continue
if(R.stat == DEAD)
continue

View File

@@ -13,4 +13,5 @@ var/global/list/living_mob_list = list() //all alive mobs, including clientles
var/global/list/dead_mob_list = list() //all dead mobs, including clientless. Excludes /mob/dead/new_player
var/global/list/joined_player_list = list() //all clients that have joined the game at round-start or as a latejoin.
var/global/list/silicon_mobs = list() //all silicon mobs
var/global/list/pai_list = list()
var/global/list/pai_list = list()
var/global/list/available_ai_shells = list()

View File

@@ -18,6 +18,14 @@
. = is_eligible_servant(new_body)
/datum/antagonist/clockcultist/give_to_body(mob/living/new_body)
if(iscyborg(new_body))
var/mob/living/silicon/robot/R = new_body
if(R.deployed)
var/mob/living/silicon/ai/AI = R.mainframe
R.undeploy()
var/converted = add_servant_of_ratvar(AI, silent_update)
to_chat(AI, "<span class='userdanger'>Anomaly Detected. Returned to core!</span>") //The AI needs to be in its core to properly be converted
return converted
if(!silent_update)
if(issilicon(new_body))
to_chat(new_body, "<span class='heavy_brass'>You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the Clockwork Justiciar, \
@@ -69,7 +77,8 @@
var/mob/living/silicon/S = owner
if(iscyborg(S))
var/mob/living/silicon/robot/R = S
R.UnlinkSelf()
if(!R.shell)
R.UnlinkSelf()
R.module.rebuild_modules()
else if(isAI(S))
var/mob/living/silicon/ai/A = S

View File

@@ -34,7 +34,11 @@
var/new_ai = select_active_ai(R)
if(new_ai && (new_ai != R.connected_ai))
R.connected_ai = new_ai
R.notify_ai(TRUE)
if(R.shell)
R.undeploy() //If this borg is an AI shell, disconnect the controlling AI and assign ti to a new AI
R.notify_ai(AI_SHELL)
else
R.notify_ai(TRUE)
if(WIRE_CAMERA) // Pulse to disable the camera.
if(!isnull(R.camera) && !R.scrambledcodes)
R.camera.toggle_cam(usr, 0)
@@ -56,11 +60,12 @@
if(WIRE_AI) // Cut the AI wire to reset AI control.
if(!mend)
R.connected_ai = null
R.undeploy() //Forced disconnect of an AI should this body be a shell.
if(WIRE_LAWSYNC) // Cut the law wire, and the borg will no longer receive law updates from its AI. Repair and it will re-sync.
if(mend)
if(!R.emagged)
R.lawupdate = TRUE
else
else if(!R.deployed) //AI shells must always have the same laws as the AI
R.lawupdate = FALSE
if (WIRE_CAMERA) // Disable the camera.
if(!isnull(R.camera) && !R.scrambledcodes)

View File

@@ -297,6 +297,28 @@
else
holder.icon_state = "hudnobatt"
//borg-AI shell tracking
/mob/living/silicon/robot/proc/diag_hud_set_aishell() //Shows tracking beacons on the mech
var/image/holder = hud_list[DIAG_TRACK_HUD]
var/icon/I = icon(icon, icon_state, dir)
holder.pixel_y = I.Height() - world.icon_size
if(!shell) //Not an AI shell
holder.icon_state = null
else if(deployed) //AI shell in use by an AI
holder.icon_state = "hudtrackingai"
else //Empty AI shell
holder.icon_state = "hudtracking"
//AI side tracking of AI shell control
/mob/living/silicon/ai/proc/diag_hud_set_deployed() //Shows tracking beacons on the mech
var/image/holder = hud_list[DIAG_TRACK_HUD]
var/icon/I = icon(icon, icon_state, dir)
holder.pixel_y = I.Height() - world.icon_size
if(!deployed_shell)
holder.icon_state = null
else //AI is currently controlling a shell
holder.icon_state = "hudtrackingai"
/*~~~~~~~~~~~~~~~~~~~~
BIG STOMPY MECHS
~~~~~~~~~~~~~~~~~~~~~*/

View File

@@ -110,7 +110,7 @@
sleep(30)
if(R)
R.SetLockdown(0)
R.notify_ai(1)
R.notify_ai(NEW_BORG)
/obj/machinery/transformer/conveyor/New()
..()

View File

@@ -206,7 +206,7 @@
lawsync = 0
O.connected_ai = null
else
O.notify_ai(1)
O.notify_ai(NEW_BORG)
if(forced_ai)
O.connected_ai = forced_ai
if(!lawsync)
@@ -248,6 +248,41 @@
else
to_chat(user, "<span class='warning'>The MMI must go in after everything else!</span>")
else if(istype(W, /obj/item/borg/upgrade/ai))
var/obj/item/borg/upgrade/ai/M = W
if(check_completion())
if(!isturf(loc))
to_chat(user, "<span class='warning'>You cannot install[M], the frame has to be standing on the ground to be perfectly precise!</span>")
return
if(!user.drop_item())
to_chat(user, "<span class='warning'>[M] is stuck to your hand!</span>")
return
qdel(M)
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot/shell(get_turf(src))
if(!aisync)
lawsync = FALSE
O.connected_ai = null
else
if(forced_ai)
O.connected_ai = forced_ai
O.notify_ai(AI_SHELL)
if(!lawsync)
O.lawupdate = FALSE
O.make_laws()
O.cell = chest.cell
chest.cell.loc = O
chest.cell = null
O.locked = panel_locked
O.job = "Cyborg"
forceMove(O)
O.robot_suit = src
if(!locomotion)
O.lockcharge = TRUE
O.update_canmove()
else if(istype(W,/obj/item/weapon/pen))
to_chat(user, "<span class='warning'>You need to use a multitool to name [src]!</span>")
else

View File

@@ -43,7 +43,7 @@
R.custom_name = heldname
R.updatename()
if(oldname == R.real_name)
R.notify_ai(3, oldname, R.real_name)
R.notify_ai(RENAME, oldname, R.real_name)
return 1
@@ -381,3 +381,22 @@
R.module.add_module(S, FALSE, TRUE)
return 1
/obj/item/borg/upgrade/ai
name = "B.O.R.I.S. module"
desc = "Bluespace Optimized Remote Intelligence Synchronization. An uplink device which takes the place of an MMI in cyborg endoskeletons, creating a robotic shell controlled by an AI."
icon_state = "boris"
origin_tech = "engineering=4;magnets=4;programming=4"
/obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/R)
if(..())
return
if(R.shell)
to_chat(usr, "<span class='warning'>This unit is already an AI shell!</span>")
return
if(R.key) //You cannot replace a player unless the key is completely removed.
to_chat(usr, "<span class='warning'>Intelligence patterns detected in this [R.braintype]. Aborting.</span>")
return
R.make_shell(src)
return TRUE

View File

@@ -84,6 +84,9 @@ var/list/ai_list = list()
var/obj/machinery/camera/portable/builtInCamera
var/obj/structure/AIcore/deactivated/linked_core //For exosuit control
var/mob/living/silicon/robot/deployed_shell = null //For shell control
var/datum/action/innate/deploy_shell/deploy_action = new
var/datum/action/innate/deploy_last_shell/redeploy_action = new
/mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
..()
@@ -138,6 +141,8 @@ var/list/ai_list = list()
radio = new /obj/item/device/radio/headset/ai(src)
aicamera = new/obj/item/device/camera/siliconcam/ai_camera(src)
deploy_action.Grant(src)
if(isturf(loc))
verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
@@ -247,13 +252,16 @@ var/list/ai_list = list()
for(var/mob/living/silicon/robot/R in connected_robots)
borg_area = get_area(R)
var/robot_status = "Nominal"
if(R.stat || !R.client)
if(R.shell)
robot_status = "AI SHELL"
else if(R.stat || !R.client)
robot_status = "OFFLINE"
else if(!R.cell || R.cell.charge <= 0)
robot_status = "DEPOWERED"
//Name, Health, Battery, Module, Area, and Status! Everything an AI wants to know about its borgies!
stat(null, text("[R.name] | S.Integrity: [R.health]% | Cell: [R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "Empty"] | \
Module: [R.designation] | Loc: [borg_area.name] | Status: [robot_status]"))
Module: [R.designation] | Loc: [borg_area.name] | Status: [robot_status]"))
stat(null, text("AI shell beacons detected: [LAZYLEN(available_ai_shells)]")) //Count of total AI shells
else
stat(null, text("Systems nonfunctional"))
@@ -791,12 +799,13 @@ var/list/ai_list = list()
if(!..())
return
if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card.
if(!mind)
to_chat(user, "<span class='warning'>No intelligence patterns detected.</span>" )
return
if(!can_be_carded)
to_chat(user, "<span class='boldwarning'>Transfer failed.</span>")
return
disconnect_shell() //If the AI is controlling a borg, force the player back to core!
if(!mind)
to_chat(user, "<span class='warning'>No intelligence patterns detected.</span>" )
return
ShutOffDoomsdayDevice()
new /obj/structure/AIcore/deactivated(loc)//Spawns a deactivated terminal at AI location.
ai_restore_power()//So the AI initially has power.
@@ -907,10 +916,73 @@ var/list/ai_list = list()
to_chat(src, "Hack complete. \The [apc] is now under your exclusive control.")
apc.update_icon()
/mob/living/silicon/ai/verb/deploy_to_shell(var/mob/living/silicon/robot/target)
set category = "AI Commands"
set name = "Deploy to Shell"
if(stat || lacks_power() || control_disabled)
to_chat(src, "<span class='danger'>Wireless networking module is offline.</span>")
return
var/list/possible = list()
for(var/borgie in available_ai_shells)
var/mob/living/silicon/robot/R = borgie
if(R.shell && !R.deployed && (R.stat != DEAD) && (!R.connected_ai ||(R.connected_ai == src)))
possible += R
if(!LAZYLEN(possible))
to_chat(src, "No usable AI shell beacons detected.")
if(!target || !(target in possible)) //If the AI is looking for a new shell, or its pre-selected shell is no longer valid
target = input(src, "Which body to control?") as null|anything in possible
if (!target || target.stat == DEAD || target.deployed || !(!target.connected_ai ||(target.connected_ai == src)))
return
else if(mind)
soullink(/datum/soullink/sharedbody, src, target)
deployed_shell = target
target.deploy_init(src)
mind.transfer_to(target)
diag_hud_set_deployed()
/datum/action/innate/deploy_shell
name = "Deploy to AI Shell"
desc = "Wirelessly control a specialized cyborg shell."
button_icon_state = "ai_shell"
/datum/action/innate/deploy_shell/Trigger()
var/mob/living/silicon/ai/AI = owner
if(!AI)
return
AI.deploy_to_shell()
/datum/action/innate/deploy_last_shell
name = "Reconnect to shell"
desc = "Reconnect to the most recently used AI shell."
button_icon_state = "ai_last_shell"
var/mob/living/silicon/robot/last_used_shell
/datum/action/innate/deploy_last_shell/Trigger()
if(!owner)
return
if(last_used_shell)
var/mob/living/silicon/ai/AI = owner
AI.deploy_to_shell(last_used_shell)
else
Remove(owner) //If the last shell is blown, destroy it.
/mob/living/silicon/ai/proc/disconnect_shell()
if(deployed_shell) //Forcibly call back AI in event of things such as damage, EMP or power loss.
to_chat(src, "<span class='danger'>Your remote connection has been reset!</span>")
deployed_shell.undeploy()
diag_hud_set_deployed()
/mob/living/silicon/ai/resist()
return
/mob/living/silicon/ai/spawned/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
if(!target_ai)
target_ai = src //cheat! just give... ourselves as the spawned AI, because that's technically correct
..()
..()

View File

@@ -22,6 +22,7 @@
return 0
/mob/living/silicon/ai/emp_act(severity)
disconnect_shell()
if (prob(30))
switch(pick(1,2))
if(1)

View File

@@ -1,21 +1,23 @@
/mob/living/silicon/ai/examine(mob/user)
var/msg = "<span class='info'>*---------*\nThis is \icon[src] <EM>[src]</EM>!\n"
if (src.stat == DEAD)
if (stat == DEAD)
msg += "<span class='deadsay'>It appears to be powered-down.</span>\n"
else
msg += "<span class='warning'>"
if (src.getBruteLoss())
if (src.getBruteLoss() < 30)
if (getBruteLoss())
if (getBruteLoss() < 30)
msg += "It looks slightly dented.\n"
else
msg += "<B>It looks severely dented!</B>\n"
if (src.getFireLoss())
if (src.getFireLoss() < 30)
if (getFireLoss())
if (getFireLoss() < 30)
msg += "It looks slightly charred.\n"
else
msg += "<B>Its casing is melted and heat-warped!</B>\n"
msg += "</span>"
if (shunted == 0 && !src.client)
if(deployed_shell)
msg += "The wireless networking light is blinking.\n"
else if (!shunted && !client)
msg += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem...\n"
msg += "*---------*</span>"

View File

@@ -65,6 +65,7 @@
health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss() - getFireLoss()
update_stat()
diag_hud_set_health()
disconnect_shell()
/mob/living/silicon/ai/update_stat()
if(status_flags & GODMODE)
@@ -163,6 +164,7 @@
update_sight()
/mob/living/silicon/ai/proc/ai_lose_power()
disconnect_shell()
aiRestorePowerRoutine = POWER_RESTORATION_START
blind_eyes(1)
update_sight()

View File

@@ -36,9 +36,11 @@
if(is_servant_of_ratvar(src) && user.Adjacent(src) && !stat) //To counter pseudo-stealth by using headlamps
msg += "<span class='warning'>Its eyes are glowing a blazing yellow!</span>\n"
switch(src.stat)
switch(stat)
if(CONSCIOUS)
if(!src.client)
if(shell)
msg += "It appears to be an [deployed ? "active" : "empty"] AI shell.\n"
else if(!client)
msg += "It appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS)
msg += "<span class='warning'>It doesn't seem to be responding.</span>\n"

View File

@@ -32,7 +32,9 @@
to_chat(who, "<b>Obey these laws:</b>")
laws.show_laws(who)
if (is_special_character(src) && connected_ai)
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 (is_special_character(src) && connected_ai)
to_chat(who, "<b>Remember, [connected_ai.name] is technically your master, but your objective comes first.</b>")
else if (connected_ai)
to_chat(who, "<b>Remember, [connected_ai.name] is your master, other AIs can be ignored.</b>")

View File

@@ -16,6 +16,10 @@
var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
var/obj/item/device/mmi/mmi = null
var/shell = FALSE
var/deployed = FALSE
var/mob/living/silicon/ai/mainframe = null
var/datum/action/innate/undeployment/undeployment_action = new
//Hud stuff
@@ -73,7 +77,7 @@
var/sight_mode = 0
var/updating = 0 //portable camera camerachunk update
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD)
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD)
var/list/upgrades = list()
@@ -129,8 +133,12 @@
update_icons()
..()
//If this body is meant to be a borg controlled by the AI player
if(shell)
make_shell()
//MMI stuff. Held togheter by magic. ~Miauw
if(!mmi || !mmi.brainmob)
else if(!mmi || !mmi.brainmob)
mmi = new (src)
mmi.brain = new /obj/item/organ/brain(mmi)
mmi.brain.name = "[real_name]'s brain"
@@ -170,6 +178,8 @@
mmi = null
if(connected_ai)
connected_ai.connected_robots -= src
if(shell)
available_ai_shells -= src
qdel(wires)
qdel(module)
qdel(eye_lights)
@@ -204,6 +214,8 @@
/mob/living/silicon/robot/proc/updatename()
if(shell)
return
var/changed_name = ""
if(custom_name)
changed_name = custom_name
@@ -424,7 +436,9 @@
update_icons()
else if(istype(W, /obj/item/weapon/screwdriver) && opened && cell) // radio
if(radio)
if(shell)
to_chat(user, "You cannot seem to open the radio compartment") //Prevent AI radio key theft
else if(radio)
radio.attackby(W,user)//Push it to the radio to let it handle everything
else
to_chat(user, "<span class='warning'>Unable to locate a radio!</span>")
@@ -453,6 +467,9 @@
if(!cell)
to_chat(user, "<span class='warning'>You need to install a power cell to do that!</span>")
return
if(shell) //AI shells always have the laws of the AI
to_chat(user, "<span class='warning'>[src] is controlled remotely! You cannot upload new laws this way!</span>")
return
if(emagged || (connected_ai && lawupdate)) //Can't be sure which, metagamers
emote("buzz-[user.name]")
return
@@ -813,12 +830,14 @@
if(!connected_ai)
return
switch(notifytype)
if(1) //New Cyborg
if(NEW_BORG) //New Cyborg
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - New cyborg connection detected: <a href='?src=\ref[connected_ai];track=[html_encode(name)]'>[name]</a></span><br>")
if(2) //New Module
if(NEW_MODULE) //New Module
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - Cyborg module change detected: [name] has loaded the [designation] module.</span><br>")
if(3) //New Name
if(RENAME) //New Name
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].</span><br>")
if(AI_SHELL) //New Shell
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - New cyborg shell detected: <a href='?src=\ref[connected_ai];track=[html_encode(name)]'>[name]</a></span><br>")
/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close = 0)
if(stat || lockcharge || low_power_mode)
@@ -901,6 +920,7 @@
update_headlamp()
diag_hud_set_status()
diag_hud_set_health()
diag_hud_set_aishell()
update_health_hud()
/mob/living/silicon/robot/revive(full_heal = 0, admin_revive = 0)
@@ -910,13 +930,13 @@
update_headlamp()
if(admin_revive)
locked = 1
notify_ai(1)
notify_ai(NEW_BORG)
. = 1
/mob/living/silicon/robot/fully_replace_character_name(oldname, newname)
..()
if(oldname != real_name)
notify_ai(3, oldname, newname)
notify_ai(RENAME, oldname, newname)
if(camera)
camera.c_tag = real_name
custom_name = newname
@@ -937,6 +957,7 @@
speed = 0
ionpulse = FALSE
revert_shell()
return 1
@@ -973,6 +994,97 @@
new_hat.forceMove(src)
update_icons()
/mob/living/silicon/robot/proc/make_shell(var/obj/item/borg/upgrade/ai/board)
if(!board)
upgrades |= new /obj/item/borg/upgrade/ai(src)
shell = TRUE
braintype = "AI Shell"
name = "[designation] AI Shell [rand(100,999)]"
real_name = name
available_ai_shells |= src
if(camera)
camera.c_tag = real_name //update the camera name too
diag_hud_set_aishell()
notify_ai(AI_SHELL)
/mob/living/silicon/robot/proc/revert_shell()
if(!shell)
return
undeploy()
for(var/obj/item/borg/upgrade/ai/boris in src)
//A player forced reset of a borg would drop the module before this is called, so this is for catching edge cases
qdel(boris)
shell = FALSE
available_ai_shells -= src
name = "Unformatted Cyborg [rand(100,999)]"
real_name = name
if(camera)
camera.c_tag = real_name
diag_hud_set_aishell()
/mob/living/silicon/robot/proc/deploy_init(var/mob/living/silicon/ai/AI)
real_name = "[AI.real_name] shell [rand(100, 999)] - [designation]" //Randomizing the name so it shows up seperately in the shells list
name = real_name
if(camera)
camera.c_tag = real_name //update the camera name too
mainframe = AI
deployed = TRUE
connected_ai = mainframe
mainframe.connected_robots |= src
lawupdate = TRUE
lawsync()
if(radio && AI.radio) //AI keeps all channels, including Syndie if it is a Traitor
if(AI.radio.syndie)
radio.make_syndie()
radio.subspace_transmission = TRUE
radio.channels = AI.radio.channels
for(var/chan in radio.channels)
radio.secure_radio_connections[chan] = add_radio(radio, radiochannels[chan])
diag_hud_set_aishell()
undeployment_action.Grant(src)
/datum/action/innate/undeployment
name = "Disconnect from shell"
desc = "Stop controlling your shell and resume normal core operations."
button_icon_state = "ai_core"
/datum/action/innate/undeployment/Trigger()
if(!..())
return FALSE
var/mob/living/silicon/robot/R = owner
R.undeploy()
return TRUE
/mob/living/silicon/robot/proc/undeploy()
if(!deployed || !mainframe)
return
mainframe.redeploy_action.Grant(mainframe)
mainframe.redeploy_action.last_used_shell = src
mind.transfer_to(mainframe)
deployed = FALSE
mainframe.deployed_shell = null
undeployment_action.Remove(src)
if(radio) //Return radio to normal
radio.recalculateChannels()
if(camera)
camera.c_tag = real_name //update the camera name too
diag_hud_set_aishell()
mainframe.diag_hud_set_deployed()
mainframe.show_laws() //Always remind the AI when switching
mainframe = null
/mob/living/silicon/robot/attack_ai(mob/user)
if(shell && (!connected_ai || connected_ai == user))
var/mob/living/silicon/ai/AI = user
AI.deploy_to_shell(src)
/mob/living/silicon/robot/shell
shell = TRUE
/mob/living/silicon/robot/MouseDrop_T(mob/living/M, mob/living/user)
. = ..()
if(!(M in buckled_mobs) && isliving(M))

View File

@@ -92,6 +92,8 @@
if(locked)
to_chat(user, "<span class='notice'>You emag the cover lock.</span>")
locked = 0
if(shell) //A warning to Traitors who may not know that emagging AI shells does not slave them.
to_chat(user, "<span class='boldwarning'>[src] seems to be controlled remotely! Emagging the interface may not work as expected.</span>")
else
to_chat(user, "<span class='warning'>The cover is already unlocked!</span>")
return
@@ -125,6 +127,12 @@
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they were slaved to traitor AI [connected_ai].")
return
if(shell) //AI shells cannot be emagged, so we try to make it look like a standard reset. Smart players may see through this, however.
to_chat(user, "<span class='danger'>[src] is remotely controlled! Your emag attempt has triggered a system reset instead!</span>")
log_game("[key_name(user)] attempted to emag an AI shell belonging to [key_name(src) ? key_name(src) : connected_ai]. The shell has been reset as a result.")
ResetModule()
return
SetEmagged(1)
SetStunned(3) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
lawupdate = 0

View File

@@ -218,7 +218,7 @@
R.SetLockdown(0)
R.anchored = FALSE
R.notransform = FALSE
R.notify_ai(2)
R.notify_ai(NEW_MODULE)
if(R.hud_used)
R.hud_used.update_robot_modules_display()
if(feedback_key && !did_feedback)

View File

@@ -21,8 +21,7 @@
var/designation = ""
var/radiomod = "" //Radio character used before state laws/arrivals announce to allow department transmissions, default, or none at all.
var/obj/item/device/camera/siliconcam/aicamera = null //photography
//hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD)
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD)
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_TRACK_HUD)
var/obj/item/device/radio/borg/radio = null //AIs dont use this but this is at the silicon level to advoid copypasta in say()

View File

@@ -385,7 +385,7 @@
R.loc = loc
R.job = "Cyborg"
R.notify_ai(1)
R.notify_ai(NEW_BORG)
. = R
qdel(src)

View File

@@ -122,7 +122,7 @@
var/mob/living/silicon/robot/Robot = M
if(Robot.mmi)
qdel(Robot.mmi)
Robot.notify_ai(1)
Robot.notify_ai(NEW_BORG)
else
for(var/obj/item/W in contents)
if(!M.dropItemToGround(W))

View File

@@ -718,6 +718,16 @@
construction_time = 120
category = list("Cyborg Upgrade Modules")
/datum/design/boris_ai_controller
name = "B.O.R.I.S. AI-Cyborg Remote Control Module"
id = "borg_ai_control"
build_type = MECHFAB
build_path = /obj/item/borg/upgrade/ai
materials = list(MAT_METAL = 1200, MAT_GLASS = 1500, MAT_GOLD = 200)
req_tech = list("programming" = 4, "magnets" = 4, "engineering" = 4)
construction_time = 50
category = list("Misc")
//Misc
/datum/design/mecha_tracking
name = "Exosuit Tracking Beacon"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB