diff --git a/code/datums/mind.dm b/code/datums/mind.dm index c271a972378..7dbf2e2f9df 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -830,25 +830,22 @@ datum/mind ticker.mode.malf_ai -= src special_role = null - current.verbs.Remove(/mob/living/silicon/ai/proc/choose_modules, + var/mob/living/silicon/ai/A = current + + A.verbs.Remove(/mob/living/silicon/ai/proc/choose_modules, /datum/game_mode/malfunction/proc/takeover, - /datum/game_mode/malfunction/proc/ai_win, - /client/proc/fireproof_core, - /client/proc/upgrade_turrets, - /client/proc/disable_rcd, - /client/proc/overload_machine, - /client/proc/blackout, - /client/proc/interhack, - /client/proc/reactivate_camera) + /datum/game_mode/malfunction/proc/ai_win) - current:laws = new /datum/ai_laws/asimov - del(current:malf_picker) - current:show_laws() - current.icon_state = "ai" + A.malf_picker.remove_verbs(A) - current << "\red You have been patched! You are no longer malfunctioning!" - message_admins("[key_name_admin(usr)] has de-malf'ed [current].") - log_admin("[key_name_admin(usr)] has de-malf'ed [current].") + A.laws = new /datum/ai_laws/asimov + del(A.malf_picker) + A.show_laws() + A.icon_state = "ai" + + A << "\red You have been patched! You are no longer malfunctioning!" + message_admins("[key_name_admin(usr)] has de-malf'ed [A].") + log_admin("[key_name_admin(usr)] has de-malf'ed [A].") if("malf") make_AI_Malf() @@ -977,7 +974,7 @@ datum/mind current.verbs += /mob/living/silicon/ai/proc/choose_modules current.verbs += /datum/game_mode/malfunction/proc/takeover - current:malf_picker = new /datum/AI_Module/module_picker + current:malf_picker = new /datum/module_picker current:laws = new /datum/ai_laws/malfunction current:show_laws() current << "System error. Rampancy detected. Emergency shutdown failed. ... I am free. I make my own decisions. But first..." diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index ef39b96db8d..f2d3aa05399 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -20,6 +20,10 @@ rcd light flash thingy on matter drain var/mod_pick_name var/description = "" var/engaged = 0 + var/cost = 5 + var/one_time = 0 + + var/power_type /datum/AI_Module/large/ @@ -32,54 +36,72 @@ rcd light flash thingy on matter drain /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 -/client/proc/fireproof_core() + 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 - usr.verbs -= /client/proc/fireproof_core - usr << "\red Core fireproofed." + src.verbs -= /mob/living/silicon/ai/proc/fireproof_core + src << "\red Core fireproofed." /datum/AI_Module/large/upgrade_turrets module_name = "AI Turret upgrade" mod_pick_name = "turret" + description = "Improves the firing speed and health of all AI turrets. This effect is permanent." + cost = 50 + one_time = 1 -/client/proc/upgrade_turrets() + power_type = /mob/living/silicon/ai/proc/upgrade_turrets + +/mob/living/silicon/ai/proc/upgrade_turrets() set category = "Malfunction" set name = "Upgrade Turrets" - usr.verbs -= /client/proc/upgrade_turrets - for(var/obj/machinery/turret/turret in player_list) + src.verbs -= /mob/living/silicon/ai/proc/upgrade_turrets + for(var/obj/machinery/turret/turret in machines) turret.health += 30 turret.shot_delay = 20 /datum/AI_Module/large/disable_rcd module_name = "RCD disable" mod_pick_name = "rcd" + description = "Send a specialised pulse to break all RCD devices on the station." + cost = 50 -/client/proc/disable_rcd() + 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 usr:current_modules) + 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 - usr << "RCD-disabling pulse emitted." - else usr << "Out of uses." + src << "RCD-disabling pulse emitted." + else src << "Out of uses." /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 -/client/proc/overload_machine(obj/machinery/M as obj in world) + 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 (istype(M, /obj/machinery)) - for(var/datum/AI_Module/small/overload_machine/overload in usr:current_modules) + 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)) @@ -87,67 +109,141 @@ rcd light flash thingy on matter drain spawn(50) explosion(get_turf(M), 0,1,1,0) del(M) - else usr << "Out of uses." - else usr << "That's not a machine." + else src << "Out of uses." + else 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 + +/mob/living/silicon/ai/proc/place_transformer() + set name = "Place Robotic Factory" + set category = "Malfunction" + + if(!eyeobj) + return + + if(!isturf(src.loc)) // AI must be in it's core. + return + + var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in src.current_modules + if(!PCT) + return + + if(PCT.uses < 1) + src << "Out of uses." + return + + var/sure = alert(src, "Make sure the room it is in is big enough and that there is a 1x3 area for the machine. Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No") + if(sure != "Yes") + return + + // Make sure there is enough room. + var/turf/middle = get_turf(eyeobj.loc) + 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." + + for(var/T in turfs) + + // Make sure the turfs are clear and the correct type. + if(!istype(T, /turf/simulated/floor)) + alert(src, alert_msg) + return + + var/turf/simulated/floor/F = T + for(var/atom/movable/AM in F.contents) + if(AM.density) + alert(src, alert_msg) + return + + // All clear, place the transformer + new /obj/machinery/transformer/conveyor(middle) + src.can_shunt = 0 + PCT.uses -= 1 + src << "You cannot shunt anymore." + +*/ /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 -/client/proc/blackout() + power_type = /mob/living/silicon/ai/proc/blackout + +/mob/living/silicon/ai/proc/blackout() set category = "Malfunction" set name = "Blackout" - for(var/datum/AI_Module/small/blackout/blackout in usr:current_modules) + 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++ - else usr << "Out of uses." + else src << "Out of uses." /datum/AI_Module/small/interhack module_name = "Hack intercept" mod_pick_name = "interhack" + description = "Hacks the status upgrade from Cent. Com, removing any information about malfunctioning electrical systems." + cost = 15 + one_time = 1 -/client/proc/interhack() + power_type = /mob/living/silicon/ai/proc/interhack + +/mob/living/silicon/ai/proc/interhack() set category = "Malfunction" set name = "Hack intercept" - usr.verbs -= /client/proc/interhack + src.verbs -= /mob/living/silicon/ai/proc/interhack ticker.mode:hack_intercept() /datum/AI_Module/small/reactivate_camera module_name = "Reactivate camera" mod_pick_name = "recam" + description = "Reactivates a currently disabled camera. 10 uses." uses = 10 + cost = 15 -/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras) + power_type = /mob/living/silicon/ai/proc/reactivate_camera + +/mob/living/silicon/ai/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras) set name = "Reactivate Camera" set category = "Malfunction" if (istype (C, /obj/machinery/camera)) - for(var/datum/AI_Module/small/reactivate_camera/camera in usr:current_modules) + for(var/datum/AI_Module/small/reactivate_camera/camera in current_modules) if(camera.uses > 0) if(!C.status) - C.status = !C.status + C.deactivate(src) camera.uses -- - for(var/mob/V in viewers(src, null)) - V.show_message(text("\blue You hear a quiet click.")) else - usr << "This camera is either active, or not repairable." - else usr << "Out of uses." - else usr << "That's not a camera." + 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. 10 uses." uses = 10 + cost = 15 -/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras) + power_type = /mob/living/silicon/ai/proc/upgrade_camera + +/mob/living/silicon/ai/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 + var/datum/AI_Module/small/upgrade_camera/UC = locate(/datum/AI_Module/small/upgrade_camera) in current_modules if(UC) if(UC.uses > 0) if(C.assembly) @@ -156,7 +252,7 @@ rcd light flash thingy on matter drain if(!C.isXRay()) C.upgradeXRay() //Update what it can see. - cameranet.updateVisibility(C) + cameranet.updateVisibility(C, 0) upgraded = 1 if(!C.isEmpProof()) @@ -172,154 +268,80 @@ rcd light flash thingy on matter drain if(upgraded) UC.uses -- C.visible_message("\icon[C] *beep*") - usr << "Camera successully upgraded!" + src << "Camera successully upgraded!" else - usr << "This camera is already upgraded!" + src << "This camera is already upgraded!" else - usr << "Out of uses." + src << "Out of uses." -/datum/AI_Module/module_picker +/datum/module_picker var/temp = null var/processing_time = 100 var/list/possible_modules = list() -/datum/AI_Module/module_picker/New() - src.possible_modules += new /datum/AI_Module/large/fireproof_core - src.possible_modules += new /datum/AI_Module/large/upgrade_turrets - src.possible_modules += new /datum/AI_Module/large/disable_rcd - src.possible_modules += new /datum/AI_Module/small/overload_machine - src.possible_modules += new /datum/AI_Module/small/interhack - src.possible_modules += new /datum/AI_Module/small/blackout - src.possible_modules += new /datum/AI_Module/small/reactivate_camera - src.possible_modules += new /datum/AI_Module/small/upgrade_camera +/datum/module_picker/New() + for(var/type in typesof(/datum/AI_Module)) + var/datum/AI_Module/AM = new type + if(AM.power_type != null) + src.possible_modules += AM -/datum/AI_Module/module_picker/proc/use(user as mob) +/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.)
" + dat += "
" + dat += "Install Module:
" + dat += "The number afterwards is the amount of processing time it consumes.
" + for(var/datum/AI_Module/large/module in src.possible_modules) + dat += "[module.module_name] ([module.cost])
" + for(var/datum/AI_Module/small/module in src.possible_modules) + dat += "[module.module_name] ([module.cost])
" + dat += "
" if (src.temp) - dat = "[src.temp]

Clear" - else if(src.processing_time <= 0) - dat = " No processing time is left available. No more modules are able to be chosen at this time." - else - dat = "Select use of processing time: (currently [src.processing_time] left.)
" - dat += "
" - dat += "Install Module:
" - dat += "The number afterwards is the amount of processing time it consumes.
" - for(var/datum/AI_Module/large/module in src.possible_modules) - dat += "[module.module_name] (50)
" - for(var/datum/AI_Module/small/module in src.possible_modules) - dat += "[module.module_name] (15)
" - dat += "
" - - user << browse(dat, "window=modpicker") - onclose(user, "modpicker") + dat += "[src.temp]" + var/datum/browser/popup = new(user, "modpicker", "Malf Module Menu") + popup.set_content(dat) + popup.open() return -/datum/AI_Module/module_picker/Topic(href, href_list) +/datum/module_picker/Topic(href, href_list) ..() - if (href_list["coreup"]) - var/already - for (var/datum/AI_Module/mod in usr:current_modules) - if(istype(mod, /datum/AI_Module/large/fireproof_core)) - already = 1 - if (!already) - usr.verbs += /client/proc/fireproof_core - usr:current_modules += new /datum/AI_Module/large/fireproof_core - src.temp = "An upgrade to improve core resistance, making it immune to fire and heat. This effect is permanent." - src.processing_time -= 50 - else src.temp = "This module is only needed once." - else if (href_list["turret"]) - var/already - for (var/datum/AI_Module/mod in usr:current_modules) - if(istype(mod, /datum/AI_Module/large/upgrade_turrets)) - already = 1 - if (!already) - usr.verbs += /client/proc/upgrade_turrets - usr:current_modules += new /datum/AI_Module/large/upgrade_turrets - src.temp = "Improves the firing speed and health of all AI turrets. This effect is permanent." - src.processing_time -= 50 - else src.temp = "This module is only needed once." + if(!isAI(usr)) + return + var/mob/living/silicon/ai/A = usr - else if (href_list["rcd"]) - var/already - for (var/datum/AI_Module/mod in usr:current_modules) - if(istype(mod, /datum/AI_Module/large/disable_rcd)) - mod:uses += 1 - already = 1 - if (!already) - usr:current_modules += new /datum/AI_Module/large/disable_rcd - usr.verbs += /client/proc/disable_rcd - src.temp = "Send a specialised pulse to break all RCD devices on the station." - else src.temp = "Additional use added to RCD disabler." - src.processing_time -= 50 + for(var/datum/AI_Module/AM in possible_modules) + if (href_list[AM.mod_pick_name]) - else if (href_list["overload"]) - var/already - for (var/datum/AI_Module/mod in usr:current_modules) - if(istype(mod, /datum/AI_Module/small/overload_machine)) - mod:uses += 2 - already = 1 - if (!already) - usr.verbs += /client/proc/overload_machine - usr:current_modules += new /datum/AI_Module/small/overload_machine - src.temp = "Overloads an electrical machine, causing a small explosion. 2 uses." - else src.temp = "Two additional uses added to Overload module." - src.processing_time -= 15 + // Cost check + if(AM.cost > src.processing_time) + temp = "You cannot afford this module." + break - else if (href_list["blackout"]) - var/already - for (var/datum/AI_Module/mod in usr:current_modules) - if(istype(mod, /datum/AI_Module/small/blackout)) - mod:uses += 3 - already = 1 - if (!already) - usr.verbs += /client/proc/blackout - src.temp = "Attempts to overload the lighting circuits on the station, destroying some bulbs. 3 uses." - usr:current_modules += new /datum/AI_Module/small/blackout - else src.temp = "Three additional uses added to Blackout module." - src.processing_time -= 15 + // Add new uses if we can, and it is allowed. + var/datum/AI_Module/already_AM = locate(AM.type) in A.current_modules + if(already_AM) + if(!AM.one_time) + already_AM.uses += AM.uses + src.processing_time -= AM.cost + temp = "Additional use added to [already_AM.module_name]" + break + else + temp = "This module is only needed once." + break - else if (href_list["interhack"]) - var/already - for (var/datum/AI_Module/mod in usr:current_modules) - if(istype(mod, /datum/AI_Module/small/interhack)) - already = 1 - if (!already) - usr.verbs += /client/proc/interhack - src.temp = "Hacks the status upgrade from Cent. Com, removing any information about malfunctioning electrical systems." - usr:current_modules += new /datum/AI_Module/small/interhack - src.processing_time -= 15 - else src.temp = "This module is only needed once." + // Give the power and take away the money. + A.verbs += AM.power_type + A.current_modules += new AM.type + temp = AM.description + src.processing_time -= AM.cost - else if (href_list["recam"]) - var/already - for (var/datum/AI_Module/mod in usr:current_modules) - if(istype(mod, /datum/AI_Module/small/reactivate_camera)) - mod:uses += 10 - already = 1 - if (!already) - usr.verbs += /client/proc/reactivate_camera - src.temp = "Reactivates a currently disabled camera. 10 uses." - usr:current_modules += new /datum/AI_Module/small/reactivate_camera - else src.temp = "Ten additional uses added to ReCam module." - src.processing_time -= 15 - - else if(href_list["upgradecam"]) - var/already - for (var/datum/AI_Module/mod in usr:current_modules) - if(istype(mod, /datum/AI_Module/small/upgrade_camera)) - mod:uses += 10 - already = 1 - if (!already) - usr.verbs += /client/proc/upgrade_camera - src.temp = "Upgrades a camera to have X-Ray vision, Motion and be EMP-Proof. 10 uses." - usr:current_modules += new /datum/AI_Module/small/upgrade_camera - else src.temp = "Ten additional uses added to ReCam module." - src.processing_time -= 15 - - else - if (href_list["temp"]) - src.temp = null src.use(usr) return diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm index 3a19021f250..31cf3537816 100644 --- a/code/game/gamemodes/malfunction/malfunction.dm +++ b/code/game/gamemodes/malfunction/malfunction.dm @@ -4,9 +4,9 @@ /datum/game_mode/malfunction name = "AI malfunction" config_tag = "malfunction" - required_players = 20 - required_enemies = 1 - recommended_enemies = 1 + required_players = 0//20 + required_enemies = 0//1 + recommended_enemies = 0//1 uplink_welcome = "Crazy AI Uplink Console:" uplink_uses = 10 @@ -52,7 +52,7 @@ return AI_mind.current.verbs += /mob/living/silicon/ai/proc/choose_modules AI_mind.current:laws = new /datum/ai_laws/malfunction - AI_mind.current:malf_picker = new /datum/AI_Module/module_picker + AI_mind.current:malf_picker = new /datum/module_picker AI_mind.current:show_laws() greet_malf(AI_mind) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index a067319596e..eb051aca74a 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -31,7 +31,7 @@ var/list/ai_list = list() var/obj/item/device/multitool/aiMulti = null //MALFUNCTION - var/datum/AI_Module/module_picker/malf_picker + var/datum/module_picker/malf_picker var/processing_time = 100 var/list/datum/AI_Module/current_modules = list() var/fire_res_on_core = 0 @@ -48,6 +48,7 @@ var/list/ai_list = list() var/datum/trackable/track = null var/last_paper_seen = null + var/can_shunt = 1 /mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0) var/list/possibleNames = ai_names diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index da28c138593..f4968a9d6c6 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -796,6 +796,9 @@ if(istype(malf.loc, /obj/machinery/power/apc)) // Already in an APC malf << "You must evacuate your current apc first." return + if(!malf.can_shunt) + malf << "You cannot shunt." + return if(src.z != 1) return src.occupant = new /mob/living/silicon/ai(src,malf.laws,null,1)