// TO DO:
/*
epilepsy flash on lights
delay round message
microwave makes robots
dampen radios
reactivate cameras - done
eject engine
core sheild
cable stun
rcd light flash thingy on matter drain
*/
/datum/AI_Module
var/uses = 0
var/module_name
var/mod_pick_name
var/description = ""
var/engaged = 0
var/cost = 5
var/one_time = 0
var/power_type
/datum/AI_Module/large/
uses = 1
/datum/AI_Module/small/
uses = 5
/datum/AI_Module/large/fireproof_core
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
one_time = 1
power_type = /mob/living/silicon/ai/proc/fireproof_core
/mob/living/silicon/ai/proc/fireproof_core()
set category = "Malfunction"
set name = "Fireproof Core"
for(var/mob/living/silicon/ai/ai in player_list)
ai.fire_res_on_core = 1
src.verbs -= /mob/living/silicon/ai/proc/fireproof_core
to_chat(src, "Core fireproofed.")
/datum/AI_Module/large/upgrade_turrets
module_name = "AI Turret Upgrade"
mod_pick_name = "turret"
description = "Improves the firing power and health of all AI turrets. This effect is permanent."
cost = 50
one_time = 1
power_type = /mob/living/silicon/ai/proc/upgrade_turrets
/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/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.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'
to_chat(src, "Turrets upgraded.")
/datum/AI_Module/large/destroy_rcd
module_name = "Destroy RCDs"
mod_pick_name = "rcd"
description = "Send a specialised pulse to detonate 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 = "Destroy RCDs"
set desc = "Detonate all RCDs on the station, while sparing onboard cyborg RCDs."
if(stat || malf_cooldown)
return
for(var/obj/item/RCD in rcd_list)
if(!istype(RCD, /obj/item/weapon/rcd/borg)) //Ensures that cyborg RCDs are spared.
RCD.audible_message("[RCD] begins to vibrate and buzz loudly!","[RCD] begins vibrating violently!")
spawn(50) //5 seconds to get rid of it!
if(RCD) //Make sure it still exists (In case of chain-reaction)
explosion(RCD, 0, 0, 3, 1, flame_range = 1)
qdel(RCD)
to_chat(src, "RCD detonation pulse emitted.")
malf_cooldown = 1
spawn(100)
malf_cooldown = 0
/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!
to_chat(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"
mod_pick_name = "overload"
description = "Overloads an electrical machine, causing a small explosion. 2 uses."
uses = 2
cost = 15
power_type = /mob/living/silicon/ai/proc/overload_machine
/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))
to_chat(src, "This machine can not be overloaded due to a firewall.")
return
for(var/datum/AI_Module/small/overload_machine/overload in current_modules)
if(overload.uses > 0)
overload.uses --
for(var/mob/V in hearers(M, null))
V.show_message("You hear a loud electrical buzzing sound!", 2)
spawn(50)
explosion(get_turf(M), 0,1,1,0)
qdel(M)
else
to_chat(src, "Out of uses.")
else
to_chat(src, "That's not a machine.")
/datum/AI_Module/small/override_machine
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
cost = 15
power_type = /mob/living/silicon/ai/proc/override_machine
/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))
to_chat(src, "This machine can not be overloaded due to a firewall.")
return
for(var/datum/AI_Module/small/override_machine/override in current_modules)
if(override.uses > 0)
override.uses --
for(var/mob/V in hearers(M, null))
V.show_message("You hear a loud electrical buzzing sound!", 2)
to_chat(src, "Reprogramming machine behaviour...")
spawn(50)
if(M)
new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, src, 1)
else
to_chat(src, "Out of uses.")
else
to_chat(src, "That's not a machine.")
/datum/AI_Module/large/place_cyborg_transformer
module_name = "Robotic Factory (Removes Shunting)"
mod_pick_name = "cyborgtransformer"
description = "Build a machine anywhere, using expensive nanomachines, that can convert a living human into a loyal cyborg slave when placed inside."
cost = 100
power_type = /mob/living/silicon/ai/proc/place_transformer
var/list/turfOverlays = list()
/datum/AI_Module/large/place_cyborg_transformer/New()
for(var/i=0;i<3;i++)
var/image/I = image("icon"='icons/turf/overlays.dmi')
turfOverlays += I
..()
/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())
return
var/turf/T = get_turf(eyeobj)
new /obj/machinery/transformer/conveyor(T)
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in current_modules
PCT.uses --
can_shunt = 0
to_chat(src, "You cannot shunt anymore.")
/mob/living/silicon/ai/proc/canPlaceTransformer()
if(!eyeobj || !isturf(src.loc))
return
var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in current_modules
if(!PCT || PCT.uses < 1)
alert(src, "Out of uses.")
return
var/turf/middle = get_turf(eyeobj)
var/list/turfs = list(middle, locate(middle.x - 1, middle.y, middle.z), locate(middle.x + 1, middle.y, middle.z))
var/alert_msg = "There isn't enough room. Make sure you are placing the machine in a clear area and on a floor."
var/success = 1
if(turfs.len == 3)
for(var/n=1;n<4,n++)
var/fail
var/turf/T = turfs[n]
if(!istype(T, /turf/simulated/floor))
fail = 1
var/datum/camerachunk/C = cameranet.getCameraChunk(T.x, T.y, T.z)
if(!C.visibleTurfs[T])
alert_msg = "We cannot get camera vision of this location."
fail = 1
for(var/atom/movable/AM in T.contents)
if(AM.density)
fail = 1
var/image/I = PCT.turfOverlays[n]
I.loc = T
client.images += I
if(fail)
success = 0
I.icon_state = "redOverlay"
else
I.icon_state = "greenOverlay"
spawn(30)
if(client && (I.loc == T))
client.images -= I
if(success)
return 1
alert(src, alert_msg)
return
/datum/AI_Module/small/blackout
module_name = "Blackout"
mod_pick_name = "blackout"
description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. 3 uses."
uses = 3
cost = 15
power_type = /mob/living/silicon/ai/proc/blackout
/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 --
for(var/obj/machinery/power/apc/apc in world)
if(prob(30*apc.overload))
apc.overload_lighting()
else
apc.overload++
to_chat(src, "Overcurrent applied to the powernet.")
else
to_chat(src, "Out of uses.")
/datum/AI_Module/small/reactivate_cameras
module_name = "Reactivate Camera Network"
mod_pick_name = "recam"
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 = /mob/living/silicon/ai/proc/reactivate_cameras
/mob/living/silicon/ai/proc/reactivate_cameras()
set name = "Reactivate Cameranet"
set category = "Malfunction"
if(stat || 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.toggle_cam(src, 1) //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
to_chat(src, "Out of uses.")
verbs -= /mob/living/silicon/ai/proc/reactivate_cameras //It is useless now, clean it up.
break
to_chat(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++
to_chat(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
var/processing_time = 100
var/list/possible_modules = list()
/datum/module_picker/New()
for(var/type in subtypesof(/datum/AI_Module))
var/datum/AI_Module/AM = new type
if(AM.power_type != null)
src.possible_modules += AM
/datum/module_picker/proc/remove_verbs(var/mob/living/silicon/ai/A)
for(var/datum/AI_Module/AM in possible_modules)
A.verbs.Remove(AM.power_type)
/datum/module_picker/proc/use(user as mob)
var/dat
dat += {"Select use of processing time: (currently #[src.processing_time] left.)