diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 4a5b588a629..4efd869751f 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -134,6 +134,11 @@
#define RESIZE_DEFAULT_SIZE 1
+//transfer_ai() defines. Main proc in ai_core.dm
+#define AI_TRANS_TO_CARD 1 //Downloading AI to InteliCard.
+#define AI_TRANS_FROM_CARD 2 //Uploading AI from InteliCard
+#define AI_MECH_HACK 3 //Malfunctioning AI hijacking mecha
+
//singularity defines
#define STAGE_ONE 1
#define STAGE_TWO 3
diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index 8c419cc35fb..690ac0e5c5b 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -17,6 +17,6 @@ var/global/list/table_recipes = list() //list of all table craft recipes
var/global/list/all_areas = list()
var/global/list/machines = list()
-var/global/list/processing_power_items = list()
- //items that ask to be called every cycle
+var/global/list/processing_power_items = list() //items that ask to be called every cycle
+var/global/list/rcd_list = list() //list of Rapid Construction Devices.
diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index ca02a66a463..ed0e976c5da 100644
--- a/code/_onclick/ai.dm
+++ b/code/_onclick/ai.dm
@@ -43,6 +43,8 @@
return
if(modifiers["middle"])
MiddleClickOn(A)
+ if(controlled_mech) //Are we piloting a mech? Placed here so the modifiers are not overridden.
+ controlled_mech.click_action(A, src) //Override AI normal click behavior.
return
if(modifiers["shift"])
ShiftClickOn(A)
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 363053d4984..a464bfc29cd 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -34,7 +34,7 @@ rcd light flash thingy on matter drain
/datum/AI_Module/large/fireproof_core
- module_name = "Core upgrade"
+ module_name = "Core Upgrade"
mod_pick_name = "coreup"
description = "An upgrade to improve core resistance, making it immune to fire and heat. This effect is permanent."
cost = 50
@@ -51,9 +51,9 @@ rcd light flash thingy on matter drain
src << "Core fireproofed."
/datum/AI_Module/large/upgrade_turrets
- module_name = "AI Turret upgrade"
+ module_name = "AI Turret Upgrade"
mod_pick_name = "turret"
- description = "Improves the firing speed and health of all AI turrets. This effect is permanent."
+ description = "Improves the firing power and health of all AI turrets. This effect is permanent."
cost = 50
one_time = 1
@@ -62,26 +62,25 @@ rcd light flash thingy on matter drain
/mob/living/silicon/ai/proc/upgrade_turrets()
set category = "Malfunction"
set name = "Upgrade Turrets"
+
+ if(stat)
+ return
+
src.verbs -= /mob/living/silicon/ai/proc/upgrade_turrets
- for(var/obj/machinery/turret/turret in machines)
- var/turf/T = get_turf(turret)
- if(T.z in config.station_levels)
- turret.health += 30
- turret.shot_delay = 20
for(var/obj/machinery/porta_turret/turret in machines)
var/turf/T = get_turf(turret)
if(T.z in config.station_levels)
// Increase health by 37.5% of original max, decrease delays between shots to 66%
turret.health += initial(turret.health) * 3 / 8
- turret.shot_delay = initial(turret.shot_delay) * 2 / 3
+ turret.eprojectile = /obj/item/projectile/beam/heavylaser //Once you see it, you will know what it means to FEAR.
+ turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg'
src << "Turrets upgraded."
/datum/AI_Module/large/lockdown
module_name = "Hostile Station Lockdown"
mod_pick_name = "lockdown"
- description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 90 seconds."
- cost = 30
- one_time = 1
+ description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 120 seconds."
+ cost = 20
power_type = /mob/living/silicon/ai/proc/lockdown
@@ -89,12 +88,11 @@ rcd light flash thingy on matter drain
set category = "Malfunction"
set name = "Initiate Hostile Lockdown"
- if(src.stat == DEAD)
- src << "You cannot begin a lockdown because you are dead!"
+ if(stat)
return
-
+
var/obj/machinery/door/airlock/AL
- for(var/obj/machinery/door/airlock/D in airlocks)
+ for(var/obj/machinery/door/D in airlocks)
if(!(D.z in config.contact_levels))
continue
spawn()
@@ -115,16 +113,16 @@ rcd light flash thingy on matter drain
verbs -= /mob/living/silicon/ai/proc/lockdown
minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.","Network Alert")
- src << "Lockdown initiated. Network reset in 90 seconds."
- spawn(900) //90 Seconds.
- disablelockdown() //Reset the lockdown after 90 seconds.
+ src << "Lockdown initiated. Network reset in two minutes."
+ spawn(1200) //120 Seconds.
+ disablelockdown() //Reset the lockdown after 120 seconds.
/mob/living/silicon/ai/proc/disablelockdown()
set category = "Malfunction"
set name = "Disable Lockdown"
var/obj/machinery/door/airlock/AL
- for(var/obj/machinery/door/airlock/D in airlocks)
+ for(var/obj/machinery/door/D in airlocks)
if(!(D.z in config.contact_levels))
continue
spawn()
@@ -141,28 +139,54 @@ rcd light flash thingy on matter drain
minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network Reset")
/datum/AI_Module/large/disable_rcd
- module_name = "RCD disable"
+ module_name = "RCD Disable"
mod_pick_name = "rcd"
- description = "Send a specialised pulse to break all RCD devices on the station."
- cost = 50
+ description = "Send a specialised pulse to break all hand-held and exosuit Rapid Cconstruction Devices on the station."
+ cost = 25
+ one_time = 1
power_type = /mob/living/silicon/ai/proc/disable_rcd
/mob/living/silicon/ai/proc/disable_rcd()
set category = "Malfunction"
set name = "Disable RCDs"
- for(var/datum/AI_Module/large/disable_rcd/rcdmod in current_modules)
- if(rcdmod.uses > 0)
- rcdmod.uses --
- for(var/obj/item/weapon/rcd/rcd in world)
- rcd.disabled = 1
- for(var/obj/item/mecha_parts/mecha_equipment/tool/rcd/rcd in world)
- rcd.disabled = 1
- src << "Out of uses."
+ set desc = "Disable all RCD devices on the station, while sparing onboard cyborg RCDs."
+
+ if(stat)
+ return
+
+ for(var/obj/item/weapon/rcd/RCD in rcd_list)
+ if(!istype(/obj/item/weapon/rcd/borg, RCD)) //Ensures that cyborg RCDs are spared.
+ RCD.disabled = 1
+ for(var/obj/item/mecha_parts/mecha_equipment/tool/rcd/MRCD in rcd_list)
+ MRCD.disabled = 1
+ src << "RCD-disabling pulse emitted."
+
+/datum/AI_Module/large/mecha_domination
+ module_name = "Viral Mech Domination"
+ mod_pick_name = "mechjack"
+ description = "Hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. Once uploaded to the mech, it is impossible to leave.\
+ Do not allow the mech to leave the station's vicinity or allow it to be destroyed."
+ cost = 30
+ one_time = 1
+
+ power_type = /mob/living/silicon/ai/proc/mech_takeover
+
+/mob/living/silicon/ai/proc/mech_takeover()
+ set name = "Compile Mecha Virus"
+ set category = "Malfunction"
+ set desc = "Target a mech by clicking it. Click the appropriate command when ready."
+
+ if(stat)
+ return
+
+ can_dominate_mechs = 1 //Yep. This is all it does. Honk!
+ src << "Virus package compiled. Select a target mech at any time. You must remain on the station at all times. Loss of signal will result in total system lockout."
+ verbs -= /mob/living/silicon/ai/proc/mech_takeover
+
/datum/AI_Module/small/overload_machine
- module_name = "Machine overload"
+ module_name = "Machine Overload"
mod_pick_name = "overload"
description = "Overloads an electrical machine, causing a small explosion. 2 uses."
uses = 2
@@ -173,6 +197,10 @@ rcd light flash thingy on matter drain
/mob/living/silicon/ai/proc/overload_machine(obj/machinery/M as obj in world)
set name = "Overload Machine"
set category = "Malfunction"
+
+ if(stat)
+ return
+
if (istype(M, /obj/machinery))
if(istype(M,/obj/machinery/field_generator))
src << "This machine can not be overloaded due to a firewall."
@@ -189,7 +217,7 @@ rcd light flash thingy on matter drain
else src << "That's not a machine."
/datum/AI_Module/small/override_machine
- module_name = "Machine override"
+ module_name = "Machine Override"
mod_pick_name = "override"
description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. 4 uses."
uses = 4
@@ -201,6 +229,10 @@ rcd light flash thingy on matter drain
/mob/living/silicon/ai/proc/override_machine(obj/machinery/M as obj in world)
set name = "Override Machine"
set category = "Malfunction"
+
+ if(stat)
+ return
+
if (istype(M, /obj/machinery))
if(istype(M,/obj/machinery/field_generator))
src << "This machine can not be overloaded due to a firewall."
@@ -234,8 +266,10 @@ rcd light flash thingy on matter drain
/mob/living/silicon/ai/proc/place_transformer()
set name = "Place Robotic Factory"
set category = "Malfunction"
+
if(!canPlaceTransformer())
return
+
var/sure = alert(src, "Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No")
if(sure == "Yes")
if(!canPlaceTransformer())
@@ -300,6 +334,10 @@ rcd light flash thingy on matter drain
/mob/living/silicon/ai/proc/blackout()
set category = "Malfunction"
set name = "Blackout"
+
+ if(stat)
+ return
+
for(var/datum/AI_Module/small/blackout/blackout in current_modules)
if(blackout.uses > 0)
blackout.uses --
@@ -310,70 +348,86 @@ rcd light flash thingy on matter drain
src << "Overcurrent applied to the powernet."
else src << "Out of uses."
-/datum/AI_Module/small/reactivate_camera
- module_name = "Reactivate camera"
+/datum/AI_Module/small/reactivate_cameras
+ module_name = "Reactivate Camera Network"
mod_pick_name = "recam"
- description = "Reactivates a currently disabled camera. 5 uses."
- uses = 5
- cost = 5
+ description = "Runs a network-wide diagnostic on the camera network, resetting focus and re-routing power to failed cameras. Can be used to repair up to 30 cameras."
+ uses = 30
+ cost = 10
+ one_time = 1
- power_type = /client/proc/reactivate_camera
+ power_type = /mob/living/silicon/ai/proc/reactivate_cameras
-/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras)
- set name = "Reactivate Camera"
+/mob/living/silicon/ai/proc/reactivate_cameras()
+ set name = "Reactivate Cameranet"
set category = "Malfunction"
- if (istype (C, /obj/machinery/camera))
- for(var/datum/AI_Module/small/reactivate_camera/camera in usr:current_modules)
+
+ if(!CanUseTopic() || malf_cooldown)
+ return
+ var/fixedcams = 0 //Tells the AI how many cams it fixed. Stats are fun.
+
+ for(var/datum/AI_Module/small/reactivate_cameras/camera in current_modules)
+ for(var/obj/machinery/camera/C in cameranet.cameras)
+ var/initial_range = initial(C.view_range) //To prevent calling the proc twice
if(camera.uses > 0)
if(!C.status)
- C.deactivate(src)
- camera.uses --
- src << "Camera reactivated."
- else
- src << "This camera is either active, or not repairable."
- else src << "Out of uses."
- else src << "That's not a camera."
-
-/datum/AI_Module/small/upgrade_camera
- module_name = "Upgrade Camera"
- mod_pick_name = "upgradecam"
- description = "Upgrades a camera to have X-Ray vision, Motion and be EMP-Proof. 5 uses."
- uses = 5
- cost = 5
-
- power_type = /client/proc/upgrade_camera
-
-/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras)
- set name = "Upgrade Camera"
- set category = "Malfunction"
- if(istype(C))
- var/datum/AI_Module/small/upgrade_camera/UC = locate(/datum/AI_Module/small/upgrade_camera) in usr:current_modules
- if(UC)
- if(UC.uses > 0)
- if(C.assembly)
- var/upgraded = 0
-
- if(!C.isXRay())
- C.upgradeXRay()
- upgraded = 1
-
- if(!C.isEmpProof())
- C.upgradeEmpProof()
- upgraded = 1
-
- if(!C.isMotion())
- C.upgradeMotion()
- upgraded = 1
-
- if(upgraded)
- UC.uses --
- C.visible_message("\icon[C] *beep*")
- src << "Camera successully upgraded!"
- else
- src << "This camera is already upgraded!"
+ C.deactivate(src, 0) //Reactivates the camera based on status. Badly named proc.
+ fixedcams++
+ camera.uses--
+ if(C.view_range != initial_range)
+ C.view_range = initial_range //Fixes cameras with bad focus.
+ camera.uses--
+ fixedcams++
+ //If a camera is both deactivated and has bad focus, it will cost two uses to fully fix!
else
- src << "Out of uses."
+ src << "Out of uses."
+ verbs -= /mob/living/silicon/ai/proc/reactivate_cameras //It is useless now, clean it up.
+ break
+ src << "Diagnostic complete! Operations completed: [fixedcams]."
+ malf_cooldown = 1
+ spawn(30) //Lag protection
+ malf_cooldown = 0
+
+/datum/AI_Module/small/upgrade_cameras
+ module_name = "Upgrade Camera Network"
+ mod_pick_name = "upgradecam"
+ description = "Install broad-spectrum scanning and electrical redundancy firmware to the camera network, enabling EMP-Proofing and light-amplified X-ray vision." //I <3 pointless technobabble
+ //This used to have motion sensing as well, but testing quickly revealed that giving it to the whole cameranet is PURE HORROR.
+ one_time = 1
+ cost = 35 //Decent price for omniscience!
+
+ power_type = /mob/living/silicon/ai/proc/upgrade_cameras
+
+/mob/living/silicon/ai/proc/upgrade_cameras()
+ set name = "Upgrade Cameranet"
+ set category = "Malfunction"
+
+ if(stat)
+ return
+
+ var/upgradedcams = 0
+ see_override = SEE_INVISIBLE_MINIMUM //Night-vision, without which X-ray would be very limited in power.
+
+ for(var/obj/machinery/camera/C in cameranet.cameras)
+ if(C.assembly)
+ var/upgraded = 0
+
+ if(!C.isXRay())
+ C.upgradeXRay()
+ //Update what it can see.
+ cameranet.updateVisibility(C, 0)
+ upgraded = 1
+
+ if(!C.isEmpProof())
+ C.upgradeEmpProof()
+ upgraded = 1
+
+ if(upgraded)
+ upgradedcams++
+
+ src << "OTA firmware distribution complete! Cameras upgraded: [upgradedcams]. Light amplification system online."
+ verbs -= /mob/living/silicon/ai/proc/upgrade_cameras
/datum/module_picker
var/temp = null
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index fdca56bd5cc..e3fb3809c39 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -127,7 +127,7 @@
/datum/game_mode/malfunction/proc/capture_the_station()
- world << "The AI has won!"
+ world << "The AI has accessed the station's core files!"
world << "It has fully taken control of all of [station_name()]'s systems."
to_nuke_or_not_to_nuke = 1
@@ -328,7 +328,8 @@
/datum/game_mode/proc/auto_declare_completion_malfunction()
if( malf_ai.len || istype(ticker.mode,/datum/game_mode/malfunction) )
var/text = "The malfunctioning AI were:"
-
+ var/module_text_temp = "
Purchased modules:
" //Added at the end
+
for(var/datum/mind/malf in malf_ai)
text += "
[malf.key] was [malf.name] ("
@@ -339,9 +340,13 @@
text += "operational"
if(malf.current.real_name != malf.name)
text += " as [malf.current.real_name]"
+ var/mob/living/silicon/ai/AI = malf.current
+ for(var/datum/AI_Module/mod in AI.current_modules)
+ module_text_temp += mod.module_name + "
"
else
text += "hardware destroyed"
text += ")"
-
+ text += module_text_temp
+
world << text
return 1
\ No newline at end of file
diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm
index 8aa64e18b6b..76fd8cf7ea5 100644
--- a/code/game/machinery/computer/ai_core.dm
+++ b/code/game/machinery/computer/ai_core.dm
@@ -233,201 +233,28 @@ This is a good place for AI-related object verbs so I'm sticking it here.
If adding stuff to this, don't forget that an AI need to cancel_camera() whenever it physically moves to a different location.
That prevents a few funky behaviors.
*/
-//What operation to perform based on target, what ineraction to perform based on object used, target itself, user. The object used is src and calls this proc.
-/obj/item/proc/transfer_ai(var/choice as text, var/interaction as text, var/target, var/mob/U as mob)
- if(!src:flush)
- switch(choice)
- if("AICORE")//AI mob.
- var/mob/living/silicon/ai/T = target
- switch(interaction)
- if("AICARD")
- var/obj/item/device/aicard/C = src
- if(C.contents.len)//If there is an AI on card.
- U << "\red Transfer failed: \black Existing AI found on this terminal. Remove existing AI to install a new one."
- else
- if (ticker.mode.name == "AI malfunction")
- var/datum/game_mode/malfunction/malf = ticker.mode
- for (var/datum/mind/malfai in malf.malf_ai)
- if (T.mind == malfai)
- U << "\red ERROR: \black Remote transfer interface disabled."//Do ho ho ho~
- return
- new /obj/structure/AIcore/deactivated(T.loc)//Spawns a deactivated terminal at AI location.
- T.aiRestorePowerRoutine = 0//So the AI initially has power.
- T.control_disabled = 1//Can't control things remotely if you're stuck in a card!
- T.loc = C//Throw AI into the card.
- C.name = "inteliCard - [T.name]"
- if (T.stat == 2)
- C.icon_state = "aicard-404"
- else
- C.icon_state = "aicard-full"
- T.cancel_camera()
- T << "You have been downloaded to a mobile storage device. Remote device connection severed."
- U << "\blue Transfer successful: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
- /*if("NINJASUIT")
- var/obj/item/clothing/suit/space/space_ninja/C = src
- if(C.AI)//If there is an AI on card.
- U << "\red Transfer failed: \black Existing AI found on this terminal. Remove existing AI to install a new one."
- else
- if (ticker.mode.name == "AI malfunction")
- var/datum/game_mode/malfunction/malf = ticker.mode
- for (var/datum/mind/malfai in malf.malf_ai)
- if (T.mind == malfai)
- U << "\red ERROR: \black Remote transfer interface disabled."
- return
- if(T.stat)//If the ai is dead/dying.
- U << "\red ERROR: \black [T.name] data core is corrupted. Unable to install."
- else
- new /obj/structure/AIcore/deactivated(T.loc)
- T.aiRestorePowerRoutine = 0
- T.control_disabled = 1
- T.loc = C
- C.AI = T
- T.cancel_camera()
- T << "You have been downloaded to a mobile storage device. Remote device connection severed."
- U << "\blue Transfer successful: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."*/
+//The type of interaction, the player performing the operation, the AI itself, and the card object, if any.
- if("INACTIVE")//Inactive AI object.
- var/obj/structure/AIcore/deactivated/T = target
- switch(interaction)
- if("AICARD")
- var/obj/item/device/aicard/C = src
- var/mob/living/silicon/ai/A = locate() in C//I love locate(). Best proc ever.
- if(A)//If AI exists on the card. Else nothing since both are empty.
- A.control_disabled = 0
- A.loc = T.loc//To replace the terminal.
- C.icon_state = "aicard"
- C.name = "inteliCard"
- C.overlays.Cut()
- A.cancel_camera()
- A << "You have been uploaded to a stationary terminal. Remote device connection restored."
- U << "\blue Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
- qdel(T)
- /*if("NINJASUIT")
- var/obj/item/clothing/suit/space/space_ninja/C = src
- var/mob/living/silicon/ai/A = C.AI
- if(A)
- A.control_disabled = 0
- C.AI = null
- A.loc = T.loc
- A.cancel_camera()
- A << "You have been uploaded to a stationary terminal. Remote device connection restored."
- U << "\blue Transfer succesful: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
- del(T)*/
- if("AIFIXER")//AI Fixer terminal.
- var/obj/machinery/computer/aifixer/T = target
- switch(interaction)
- if("AICARD")
- var/obj/item/device/aicard/C = src
- if(!T.contents.len)
- if (!C.contents.len)
- U << "No AI to copy over!"//Well duh
- else for(var/mob/living/silicon/ai/A in C)
- C.icon_state = "aicard"
- C.name = "inteliCard"
- C.overlays.Cut()
- A.loc = T
- T.occupant = A
- A.control_disabled = 1
- if (A.stat == 2)
- T.overlays += image('icons/obj/computer.dmi', "ai-fixer-404")
- else
- T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
- T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-empty")
- A.cancel_camera()
- A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
- U << "\blue Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
- else
- if(!C.contents.len && T.occupant && !T.active)
- C.name = "inteliCard - [T.occupant.name]"
- T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
- if (T.occupant.stat == 2)
- C.icon_state = "aicard-404"
- T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404")
- else
- C.icon_state = "aicard-full"
- T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full")
- T.occupant << "You have been downloaded to a mobile storage device. Still no remote access."
- U << "\blue Transfer succesful: \black [T.occupant.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
- T.occupant.loc = C
- T.occupant.cancel_camera()
- T.occupant = null
- else if (C.contents.len)
- U << "\red ERROR: \black Artificial intelligence detected on terminal."
- else if (T.active)
- U << "\red ERROR: \black Reconstruction in progress."
- else if (!T.occupant)
- U << "\red ERROR: \black Unable to locate artificial intelligence."
- /*if("NINJASUIT")
- var/obj/item/clothing/suit/space/space_ninja/C = src
- if(!T.contents.len)
- if (!C.AI)
- U << "No AI to copy over!"
- else
- var/mob/living/silicon/ai/A = C.AI
- A.loc = T
- T.occupant = A
- C.AI = null
- A.control_disabled = 1
- T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
- T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-empty")
- A.cancel_camera()
- A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
- U << "\blue Transfer successful: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
- else
- if(!C.AI && T.occupant && !T.active)
- if (T.occupant.stat)
- U << "\red ERROR: \black [T.occupant.name] data core is corrupted. Unable to install."
- else
- T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
- T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full")
- T.occupant << "You have been downloaded to a mobile storage device. Still no remote access."
- U << "\blue Transfer successful: \black [T.occupant.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
- T.occupant.loc = C
- T.occupant.cancel_camera()
- T.occupant = null
- else if (C.AI)
- U << "\red ERROR: \black Artificial intelligence detected on terminal."
- else if (T.active)
- U << "\red ERROR: \black Reconstruction in progress."
- else if (!T.occupant)
- U << "\red ERROR: \black Unable to locate artificial intelligence."*/
- /*if("NINJASUIT")//Ninjasuit
- var/obj/item/clothing/suit/space/space_ninja/T = target
- switch(interaction)
- if("AICARD")
- var/obj/item/device/aicard/C = src
- if(T.s_initialized&&U==T.affecting)//If the suit is initialized and the actor is the user.
- var/mob/living/silicon/ai/A_T = locate() in C//Determine if there is an AI on target card. Saves time when checking later.
- var/mob/living/silicon/ai/A = T.AI//Deterine if there is an AI in suit.
+atom/proc/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
+ if(istype(card))
+ if(card.flush)
+ user << "ERROR: AI flush is in progress, cannot execute transfer protocol."
+ return 0
+ return 1
- if(A)//If the host AI card is not empty.
- if(A_T)//If there is an AI on the target card.
- U << "\red ERROR: \black [A_T.name] already installed. Remove [A_T.name] to install a new one."
- else
- A.loc = C//Throw them into the target card. Since they are already on a card, transfer is easy.
- C.name = "inteliCard - [A.name]"
- C.icon_state = "aicard-full"
- T.AI = null
- A.cancel_camera()
- A << "You have been uploaded to a mobile storage device."
- U << "\blue SUCCESS: \black [A.name] ([rand(1000,9999)].exe) removed from host and stored within local memory."
- else//If host AI is empty.
- if(C.flush)//If the other card is flushing.
- U << "\red ERROR: \black AI flush is in progress, cannot execute transfer protocol."
- else
- if(A_T&&!A_T.stat)//If there is an AI on the target card and it's not inactive.
- A_T.loc = T//Throw them into suit.
- C.icon_state = "aicard"
- C.name = "inteliCard"
- C.overlays.Cut()
- T.AI = A_T
- A_T.cancel_camera()
- A_T << "You have been uploaded to a mobile storage device."
- U << "\blue SUCCESS: \black [A_T.name] ([rand(1000,9999)].exe) removed from local memory and installed to host."
- else if(A_T)//If the target AI is dead. Else just go to return since nothing would happen if both are empty.
- U << "\red ERROR: \black [A_T.name] data core is corrupted. Unable to install."*/
- else
- U << "\red ERROR: \black AI flush is in progress, cannot execute transfer protocol."
- return
\ No newline at end of file
+/obj/structure/AIcore/deactivated/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
+ if(!..())
+ return
+ //Transferring a carded AI to a core.
+ if(interaction == AI_TRANS_FROM_CARD)
+ AI.control_disabled = 0
+ AI.aiRadio.disabledAi = 0
+ AI.loc = loc//To replace the terminal.
+ AI << "You have been uploaded to a stationary terminal. Remote device connection restored."
+ user << "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
+ qdel(src)
+ else //If for some reason you use an empty card on an empty AI terminal.
+ user << "There is no AI loaded on this terminal!"
+
\ No newline at end of file
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index d291c65ac78..20d715a3a0e 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -10,28 +10,26 @@
light_color = LIGHT_COLOR_PURPLE
-/obj/machinery/computer/aifixer/New()
- src.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
-
-
/obj/machinery/computer/aifixer/attackby(I as obj, user as mob, params)
- if(istype(I, /obj/item/device/aicard))
+ if(occupant && istype(I, /obj/item/weapon/screwdriver))
if(stat & (NOPOWER|BROKEN))
- user << "This terminal isn't functioning right now, get it working!"
- return
- I:transfer_ai("AIFIXER","AICARD",src,user)
-
- ..()
- return
-
+ user << "The screws on [name]'s screen won't budge."
+ else
+ user << "The screws on [name]'s screen won't budge and it emits a warning beep."
+ return
+ else
+ ..()
+
/obj/machinery/computer/aifixer/attack_ai(var/mob/user as mob)
- return attack_hand(user)
+ return interact(user)
/obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob)
if(..())
return
+
+ interact(user)
- user.set_machine(src)
+/obj/machinery/computer/aifixer/interact(mob/user)
var/dat = "