Merge pull request #5355 from Fox-McCloud/malf-ai-update

Malf AI Powers Update
This commit is contained in:
TheDZD
2016-08-08 21:30:12 -04:00
committed by GitHub
13 changed files with 236 additions and 118 deletions
+144 -71
View File
@@ -1,19 +1,3 @@
// 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
@@ -25,7 +9,6 @@ rcd light flash thingy on matter drain
var/power_type
/datum/AI_Module/large/
uses = 1
@@ -33,28 +16,11 @@ rcd light flash thingy on matter drain
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, "<span class='notice'>Core fireproofed.</span>")
/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
description = "Improves the power and health of all AI turrets. This effect is permanent."
cost = 30
one_time = 1
power_type = /mob/living/silicon/ai/proc/upgrade_turrets
@@ -71,11 +37,46 @@ rcd light flash thingy on matter drain
var/turf/T = get_turf(turret)
// TODO: Tie into space manager
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.health += 30
turret.eprojectile = /obj/item/projectile/beam/laser/heavylaser //Once you see it, you will know what it means to FEAR.
turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg'
to_chat(src, "<span class='notice'>Turrets upgraded.</span>")
/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
power_type = /mob/living/silicon/ai/proc/lockdown
/mob/living/silicon/ai/proc/lockdown()
set category = "Malfunction"
set name = "Initiate Hostile Lockdown"
if(stat)
return
for(var/obj/machinery/door/D in airlocks)
if(D.z != ZLEVEL_STATION)
continue
spawn(0)
D.hostile_lockdown(src)
addtimer(D, "disable_lockdown", 900)
var/obj/machinery/computer/communications/C = locate() in machines
if(C)
C.post_status("alert", "lockdown")
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")
to_chat(src, "<span class='warning'>Lockdown Initiated. Network reset in 90 seconds.</span>")
spawn(900)
minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network reset:")
/datum/AI_Module/large/destroy_rcd
module_name = "Destroy RCDs"
mod_pick_name = "rcd"
@@ -93,19 +94,16 @@ rcd light flash thingy on matter drain
if(stat || malf_cooldown)
return
for(var/obj/item/RCD in rcd_list)
for(var/obj/item/weapon/rcd/RCD in rcd_list)
if(!istype(RCD, /obj/item/weapon/rcd/borg)) //Ensures that cyborg RCDs are spared.
RCD.audible_message("<span class='danger'><b>[RCD] begins to vibrate and buzz loudly!</b></span>","<span class='danger'><b>[RCD] begins vibrating violently!</b></span>")
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)
RCD.detonate_pulse()
to_chat(src, "<span class='danger'>RCD detonation pulse emitted.</span>")
malf_cooldown = 1
spawn(100)
malf_cooldown = 0
/datum/AI_Module/large/mecha_domination
module_name = "Viral Mech Domination"
mod_pick_name = "mechjack"
@@ -125,21 +123,71 @@ rcd light flash thingy on matter drain
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. \
<b>You must remain on the station at all times. Loss of signal will result in total system lockout.</b>")
to_chat(src, "Virus package compiled. Select a target mech at any time. <b>You must remain on the station at all times. Loss of signal will result in total system lockout.</b>")
verbs -= /mob/living/silicon/ai/proc/mech_takeover
/datum/AI_Module/large/break_fire_alarms
module_name = "Thermal Sensor Override"
mod_pick_name = "burnpigs"
description = "Gives you the ability to override the thermal sensors on all fire alarms. This will remove their ability to scan for fire and thus their ability to alert. \
Anyone can check the fire alarm's interface and may be tipped off by its status."
one_time = 1
cost = 25
power_type = /mob/living/silicon/ai/proc/break_fire_alarms
/mob/living/silicon/ai/proc/break_fire_alarms()
set name = "Override Thermal Sensors"
set category = "Malfunction"
if(stat)
return
for(var/obj/machinery/firealarm/F in machines)
if(F.z != ZLEVEL_STATION)
continue
F.emagged = 1
to_chat(src, "<span class='notice'>All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.</span>")
verbs -= /mob/living/silicon/ai/proc/break_fire_alarms
/datum/AI_Module/large/break_air_alarms
module_name = "Air Alarm Safety Override"
mod_pick_name = "allow_flooding"
description = "Gives you the ability to disable safeties on all air alarms. This will allow you to use the environmental mode Flood, which disables scrubbers as well as pressure checks on vents. \
Anyone can check the air alarm's interface and may be tipped off by their nonfunctionality."
one_time = 1
cost = 50
power_type = /mob/living/silicon/ai/proc/break_air_alarms
/mob/living/silicon/ai/proc/break_air_alarms()
set name = "Disable Air Alarm Safeties"
set category = "Malfunction"
if(stat)
return
for(var/obj/machinery/alarm/AA in machines)
if(AA.z != ZLEVEL_STATION)
continue
AA.emagged = 1
to_chat(src, "<span class='notice'>All air alarm safeties on the station have been overriden. Air alarms may now use the Flood environmental mode.")
verbs -= /mob/living/silicon/ai/proc/break_air_alarms
/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
cost = 20
power_type = /mob/living/silicon/ai/proc/overload_machine
/mob/living/silicon/ai/proc/overload_machine(obj/machinery/M as obj in world)
/mob/living/silicon/ai/proc/overload_machine(obj/machinery/M in machines)
set name = "Overload Machine"
set category = "Malfunction"
@@ -147,56 +195,55 @@ rcd light flash thingy on matter drain
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("<span class='notice'>You hear a loud electrical buzzing sound!</span>", 2)
audible_message("<span class='italics'>You hear a loud electrical buzzing sound!</span>")
to_chat(src, "<span class='warning'>Overloading machine circuitry...</span>")
spawn(50)
explosion(get_turf(M), 0,1,1,0)
qdel(M)
if(M)
explosion(get_turf(M), 0,1,1,0)
qdel(M)
else
to_chat(src, "<span class='warning'>Out of uses.</span>")
to_chat(src, "<span class='notice'>Out of uses.</span>")
else
to_chat(src, "<span class='notice'>That's not a machine.</span>")
/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
cost = 30
power_type = /mob/living/silicon/ai/proc/override_machine
/mob/living/silicon/ai/proc/override_machine(obj/machinery/M as obj in world)
/mob/living/silicon/ai/proc/override_machine(obj/machinery/M in machines)
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
if (istype(M, /obj/machinery))
if(!M.can_be_overridden())
to_chat(src, "Can't override this device.")
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("<span class='notice'>You hear a loud electrical buzzing sound!</span>", 2)
audible_message("<span class='italics'>You hear a loud electrical buzzing sound!</span>")
to_chat(src, "<span class='warning'>Reprogramming machine behaviour...</span>")
spawn(50)
if(M)
if(M && !qdeleted(M))
new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, src, 1)
else
to_chat(src, "<span class='warning'>Out of uses.</span>")
to_chat(src, "<span class='notice'>Out of uses.</span>")
else
to_chat(src, "<span class='notice'>That's not a machine.</span>")
/datum/AI_Module/large/place_cyborg_transformer
module_name = "Robotic Factory (Removes Shunting)"
mod_pick_name = "cyborgtransformer"
@@ -268,7 +315,7 @@ rcd light flash thingy on matter drain
if(success)
return 1
alert(src, alert_msg)
return
/datum/AI_Module/small/blackout
module_name = "Blackout"
@@ -298,6 +345,7 @@ rcd light flash thingy on matter drain
else
to_chat(src, "<span class='warning'>Out of uses.</span>")
/datum/AI_Module/small/reactivate_cameras
module_name = "Reactivate Camera Network"
mod_pick_name = "recam"
@@ -339,7 +387,8 @@ rcd light flash thingy on matter drain
spawn(30) //Lag protection
malf_cooldown = 0
/datum/AI_Module/small/upgrade_cameras
/datum/AI_Module/large/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
@@ -358,6 +407,7 @@ rcd light flash thingy on matter drain
var/upgradedcams = 0
see_override = SEE_INVISIBLE_MINIMUM //Night-vision, without which X-ray would be very limited in power.
update_sight()
for(var/obj/machinery/camera/C in cameranet.cameras)
if(C.assembly)
@@ -379,6 +429,26 @@ rcd light flash thingy on matter drain
to_chat(src, "<span class='notice'>OTA firmware distribution complete! Cameras upgraded: [upgradedcams]. Light amplification system online.</span>")
verbs -= /mob/living/silicon/ai/proc/upgrade_cameras
/datum/AI_Module/large/eavesdrop
module_name = "Enhanced Surveillance"
mod_pick_name = "eavesdrop"
description = "Via a combination of hidden microphones and lip reading software, you are able to use your cameras to listen in on conversations."
cost = 30
one_time = 1
power_type = /mob/living/silicon/ai/proc/surveillance
/mob/living/silicon/ai/proc/surveillance()
set category = "Malfunction"
set name = "Enhanced Surveillance"
if(eyeobj)
eyeobj.relay_speech = TRUE
to_chat(src, "<span class='notice'>OTA firmware distribution complete! Cameras upgraded: Enhanced surveillance package online.</span>")
verbs -= /mob/living/silicon/ai/proc/surveillance
/datum/module_picker
var/temp = null
var/processing_time = 100
@@ -421,6 +491,10 @@ rcd light flash thingy on matter drain
return
var/mob/living/silicon/ai/A = usr
if(A.stat == DEAD)
to_chat(A, "You are already dead!") //Omae Wa Mou Shindeiru
return
for(var/datum/AI_Module/AM in possible_modules)
if(href_list[AM.mod_pick_name])
@@ -442,6 +516,7 @@ rcd light flash thingy on matter drain
break
// Give the power and take away the money.
A.view_core() //A BYOND bug requires you to be viewing your core before your verbs update
A.verbs += AM.power_type
A.current_modules += new AM.type
temp = AM.description
@@ -450,6 +525,4 @@ rcd light flash thingy on matter drain
if(href_list["showdesc"])
if(AM.mod_pick_name == href_list["showdesc"])
temp = AM.description
src.use(usr)
return
use(usr)
+1 -1
View File
@@ -710,7 +710,7 @@
data["rcon"] = rcon_setting
data["target_temp"] = target_temperature - T0C
data["atmos_alarm"] = alarm_area.atmosalm
data["emagged"] = emagged || isAI(user)
data["emagged"] = emagged
data["modes"] = list(
AALARM_MODE_SCRUBBING = list("name"="Filtering", "desc"="Scrubs out contaminants"),\
AALARM_MODE_VENTING = list("name"="Draught", "desc"="Siphons out air while replacing"),\
+20 -1
View File
@@ -1069,4 +1069,23 @@ About the new airlock wires panel:
src.unlock()
src.open()
src.lock()
return
/obj/machinery/door/airlock/hostile_lockdown(mob/origin)
// Must be powered and have working AI wire.
if(canAIControl(src) && !stat)
locked = FALSE //For airlocks that were bolted open.
safe = FALSE //DOOR CRUSH
close()
lock() //Bolt it!
electrified_until = -1 //Shock it!
if(origin)
shockedby += "\[[time_stamp()]\][origin](ckey:[origin.ckey])"
/obj/machinery/door/airlock/disable_lockdown()
// Must be powered and have working AI wire.
if(canAIControl(src) && !stat)
unlock()
electrified_until = 0
open()
safe = TRUE
+1 -2
View File
@@ -10,8 +10,7 @@ obj/machinery/door/airlock
obj/machinery/door/airlock/process()
if(arePowerSystemsOn() && cur_command)
spawn()
execute_current_command()
execute_current_command()
else
return PROCESS_KILL
+8
View File
@@ -301,3 +301,11 @@
/obj/machinery/door/morgue
icon = 'icons/obj/doors/doormorgue.dmi'
/obj/machinery/door/proc/hostile_lockdown(mob/origin)
if(!stat) //So that only powered doors are closed.
close() //Close ALL the doors!
/obj/machinery/door/proc/disable_lockdown()
if(!stat) //Opens only powered doors.
open() //Open everything!
+10 -8
View File
@@ -49,10 +49,17 @@ FIRE ALARM
else
icon_state = "fire0"
/obj/machinery/firealarm/emag_act(mob/user)
if(!emagged)
emagged = 1
if(user)
user.visible_message("<span class='warning'>Sparks fly out of the [src]!</span>",
"<span class='notice'>You emag [src], disabling its thermal sensors.</span>")
playsound(loc, 'sound/effects/sparks4.ogg', 50, 1)
/obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume)
if(detecting)
if(temperature > T0C+200)
alarm() // added check of detector status here
if(!emagged && detecting && temperature > T0C + 200)
alarm() // added check of detector status here
/obj/machinery/firealarm/attack_ai(mob/user as mob)
src.add_hiddenprint(user)
@@ -148,11 +155,6 @@ FIRE ALARM
updateDialog()
last_process = world.timeofday
if(locate(/obj/effect/hotspot) in loc)
alarm()
return
/obj/machinery/firealarm/power_change()
if(powered(ENVIRON))
stat &= ~NOPOWER
+2 -15
View File
@@ -108,21 +108,8 @@ var/const/HOLOPAD_MODE = 0
/*This is the proc for special two-way communication between AI and holopad/people talking near holopad.
For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/machinery/hologram/holopad/hear_talk(mob/living/M, text, verb, datum/language/speaking)
if(M&&hologram&&master)//Master is mostly a safety in case lag hits or something.
if(!master.say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad.
if(speaking)
text = speaking.scramble(text)
else
text = stars(text)
var/name_used = M.GetVoice()
//This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only.
var/rendered
if(speaking)
rendered = "<i><span class='game say'>Holopad received, <span class='name'>[name_used]</span> [speaking.format_message(text, verb)]</span></i>"
else
rendered = "<i><span class='game say'>Holopad received, <span class='name'>[name_used]</span> [verb], <span class='message'>\"[text]\"</span></span></i>"
master.show_message(rendered, 2)
return
if(M && hologram && master)//Master is mostly a safety in case lag hits or something.
master.relay_speech(M, text, verb, speaking)
/obj/machinery/hologram/holopad/hear_message(mob/living/M, text)
if(M&&hologram&&master)//Master is mostly a safety in case lag hits or something.
+3
View File
@@ -548,6 +548,9 @@ Class Procs:
/obj/machinery/proc/construction()
return
/obj/machinery/proc/can_be_overridden()
. = 1
/obj/machinery/tesla_act(var/power)
..()
if(prob(85))
+25 -13
View File
@@ -91,13 +91,13 @@ RCD
data["max_matter"] = max_matter
data["one_access"] = one_access
data["locked"] = locked
if(menu == 2)
var/list/door_types_list = list()
for(var/type in allowed_door_types)
door_types_list[++door_types_list.len] = list("name" = allowed_door_types[type], "type" = type)
data["allowed_door_types"] = door_types_list
data["door_accesses"] = door_accesses_list
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
@@ -110,14 +110,14 @@ RCD
/obj/item/weapon/rcd/Topic(href, href_list, nowindow, state)
if(..())
return 1
if(prob(20))
spark_system.start()
if(href_list["mode"])
mode = text2num(href_list["mode"])
. = 1
if(href_list["door_type"])
var/new_door_type = text2path(href_list["door_type"])
if(!(new_door_type in allowed_door_types))
@@ -125,11 +125,11 @@ RCD
return
door_type = new_door_type
. = 1
if(href_list["menu"])
menu = text2num(href_list["menu"])
. = 1
if(href_list["login"])
if(istype(usr,/mob/living/silicon))
locked = 0
@@ -142,15 +142,15 @@ RCD
if(istype(ID) && ID && check_access(ID))
locked = 0
. = 1
if(href_list["logout"])
locked = 1
. = 1
if(href_list["toggle_one_access"] && !locked)
one_access = !one_access
. = 1
if(href_list["toggle_access"] && !locked)
var/href_access = text2num(href_list["toggle_access"])
if(href_access in door_accesses)
@@ -251,10 +251,10 @@ RCD
qdel(A)
return 1
return 0
if(istype(A, /obj/structure/window)) // You mean the grille of course, do you?
A = locate(/obj/structure/grille) in A.loc
if(istype(A, /obj/structure/grille))
if(!checkResource(2, user))
return 0
@@ -326,7 +326,7 @@ RCD
else
to_chat(user, "ERROR: RCD in MODE: [mode] attempted use by [user]. Send this text #coderbus or an admin.")
return 0
nanomanager.update_uis(src)
/obj/item/weapon/rcd/proc/useResource(var/amount, var/mob/user)
@@ -354,6 +354,18 @@ RCD
desc = "A device used to rapidly build and deconstruct walls and floors."
canRwall = 1
/obj/item/weapon/rcd/proc/detonate_pulse()
audible_message("<span class='danger'><b>[src] begins to vibrate and \
buzz loudly!</b></span>","<span class='danger'><b>[src] begins \
vibrating violently!</b></span>")
// 5 seconds to get rid of it
addtimer(src, "detonate_pulse_explode", 50)
/obj/item/weapon/rcd/proc/detonate_pulse_explode()
explosion(src, 0, 0, 3, 1, flame_range = 1)
qdel(src)
/obj/item/weapon/rcd/combat
name = "combat RCD"
max_matter = 500
+15 -1
View File
@@ -62,7 +62,6 @@ var/list/ai_verbs_default = list(
var/datum/module_picker/malf_picker
var/processing_time = 100
var/list/datum/AI_Module/current_modules = list()
var/fire_res_on_core = 0
var/can_dominate_mechs = 0
var/control_disabled = 0 // Set to 1 to stop AI from interacting via Click() -- TLE
var/malfhacking = 0 // More or less a copy of the above var, so that malf AIs can hack and still get new cyborgs -- NeoFite
@@ -1136,3 +1135,18 @@ var/list/ai_verbs_default = list(
eyeobj.setLoc(get_turf(C))
client.eye = eyeobj
return 1
/mob/living/silicon/ai/proc/relay_speech(mob/living/M, text, verb, datum/language/speaking)
if(!say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad.
if(speaking)
text = speaking.scramble(text)
else
text = stars(text)
var/name_used = M.GetVoice()
//This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only.
var/rendered
if(speaking)
rendered = "<i><span class='game say'>Relayed Speech: <span class='name'>[name_used]</span> [speaking.format_message(text, verb)]</span></i>"
else
rendered = "<i><span class='game say'>Relayed Speech: <span class='name'>[name_used]</span> [verb], <span class='message'>\"[text]\"</span></span></i>"
show_message(rendered, 2)
@@ -116,3 +116,7 @@
return //won't work if dead
acceleration = !acceleration
to_chat(usr, "Camera acceleration has been toggled [acceleration ? "on" : "off"].")
/mob/camera/aiEye/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
if(relay_speech)
ai.relay_speech(speaker, message, verb, language)
+1 -4
View File
@@ -152,10 +152,7 @@
health = 100
stat = CONSCIOUS
else
if(fire_res_on_core)
health = 100 - getOxyLoss() - getToxLoss() - getBruteLoss()
else
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
diag_hud_set_status()
diag_hud_set_health()
@@ -127,11 +127,12 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca
/mob/living/simple_animal/hostile/mimic/copy/Life()
..()
if(!target && !ckey) //Objects eventually revert to normal if no one is around to terrorize
adjustBruteLoss(1)
for(var/mob/living/M in contents) //a fix for animated statues from the flesh to stone spell
death()
/mob/living/simple_animal/hostile/mimic/copy/death(gibbed)
for(var/atom/movable/M in src)
M.loc = get_turf(src)
..()
@@ -186,7 +187,6 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca
if(destroy_original)
qdel(O)
return 1
return
/mob/living/simple_animal/hostile/mimic/copy/DestroySurroundings()
if(destroy_objects)