diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 79be989d0d6..946fbeaabf8 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -1,3 +1,9 @@ +#define EMPTY_CORE 0 +#define CIRCUIT_CORE 1 +#define SCREWED_CORE 2 +#define CABLED_CORE 3 +#define GLASS_CORE 4 + /obj/structure/AIcore density = 1 anchored = 0 @@ -25,193 +31,178 @@ return ..() /obj/structure/AIcore/attackby(obj/item/P, mob/user, params) - switch(state) - if(0) - if(istype(P, /obj/item/weapon/wrench)) - playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) - user << "You start wrenching the frame into place..." - if(do_after(user, 20/P.toolspeed, target = src)) - user << "You wrench the frame into place." - anchored = 1 - state = 1 + if(istype(P, /obj/item/weapon/wrench)) + playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message("[user] [anchored ? "fastens" : "unfastens"] [src].", \ + "You start to [anchored ? "unfasten [src] from" : "fasten [src] to"] the floor...") + if(do_after(user, 20/P.toolspeed, target = src)) + user << "You [anchored ? "unfasten [src] from" : "fasten [src] to"] the floor." + anchored = !anchored + return + if(!anchored) + if(istype(P, /obj/item/weapon/weldingtool)) + if(state != EMPTY_CORE) + user << "The core must be empty to deconstruct it!" return - if(istype(P, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = P - if(!WT.isOn()) - user << "The welder must be on for this task!" - return - playsound(loc, 'sound/items/Welder.ogg', 50, 1) - user << "You start to deconstruct the frame..." - if(do_after(user, 20/P.toolspeed, target = src)) - if(!src || !WT.remove_fuel(0, user)) return - user << "You deconstruct the frame." - new /obj/item/stack/sheet/plasteel( loc, 4) - qdel(src) + var/obj/item/weapon/weldingtool/WT = P + if(!WT.isOn()) + user << "The welder must be on for this task!" return - if(1) - if(istype(P, /obj/item/weapon/wrench)) - playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) - user << "You start to unfasten the frame..." - if(do_after(user, 20/P.toolspeed, target = src)) - user << "You unfasten the frame." - anchored = 0 - state = 0 - return - if(istype(P, /obj/item/weapon/circuitboard/aicore) && !circuit) - if(!user.drop_item()) - return - playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) - user << "You place the circuit board inside the frame." - icon_state = "1" - circuit = P - P.loc = src - return - if(istype(P, /obj/item/weapon/screwdriver) && circuit) - playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) - user << "You screw the circuit board into place." - state = 2 - icon_state = "2" - return - if(istype(P, /obj/item/weapon/crowbar) && circuit) - playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) - user << "You remove the circuit board." - state = 1 - icon_state = "0" - circuit.loc = loc - circuit = null - return - if(2) - if(istype(P, /obj/item/weapon/screwdriver) && circuit) - playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) - user << "You unfasten the circuit board." - state = 1 - icon_state = "1" - return - if(istype(P, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = P - if(C.get_amount() >= 5) + playsound(loc, 'sound/items/Welder.ogg', 50, 1) + user << "You start to deconstruct the frame..." + if(do_after(user, 20/P.toolspeed, target = src) && src && state == EMPTY_CORE && WT && WT.remove_fuel(0, user)) + user << "You deconstruct the frame." + deconstruct(TRUE) + return + else + switch(state) + if(EMPTY_CORE) + if(istype(P, /obj/item/weapon/circuitboard/aicore)) + if(!user.drop_item()) + return playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) - user << "You start to add cables to the frame..." - if(do_after(user, 20, target = src)) - if (C.get_amount() >= 5 && state == 2) - C.use(5) - user << "You add cables to the frame." - state = 3 - icon_state = "3" - else - user << "You need five lengths of cable to wire the AI core!" - return - if(3) - if(istype(P, /obj/item/weapon/wirecutters)) - if (brain) - user << "Get that brain out of there first!" - else - playsound(loc, 'sound/items/Wirecutter.ogg', 50, 1) - user << "You remove the cables." - state = 2 + user << "You place the circuit board inside the frame." + icon_state = "1" + state = CIRCUIT_CORE + circuit = P + P.forceMove(src) + return + if(CIRCUIT_CORE) + if(istype(P, /obj/item/weapon/screwdriver)) + playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) + user << "You screw the circuit board into place." + state = SCREWED_CORE icon_state = "2" - new /obj/item/stack/cable_coil(loc, 5) - return + return + if(istype(P, /obj/item/weapon/crowbar)) + playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) + user << "You remove the circuit board." + state = EMPTY_CORE + icon_state = "0" + circuit.forceMove(loc) + circuit = null + return + if(SCREWED_CORE) + if(istype(P, /obj/item/weapon/screwdriver) && circuit) + playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) + user << "You unfasten the circuit board." + state = CIRCUIT_CORE + icon_state = "1" + return + if(istype(P, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = P + if(C.get_amount() >= 5) + playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) + user << "You start to add cables to the frame..." + if(do_after(user, 20, target = src) && state == SCREWED_CORE && C.use(5)) + user << "You add cables to the frame." + state = CABLED_CORE + icon_state = "3" + else + user << "You need five lengths of cable to wire the AI core!" + return + if(CABLED_CORE) + if(istype(P, /obj/item/weapon/wirecutters)) + if (brain) + user << "Get that brain out of there first!" + else + playsound(loc, 'sound/items/Wirecutter.ogg', 50, 1) + user << "You remove the cables." + state = SCREWED_CORE + icon_state = "2" + var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( loc ) + A.amount = 5 + return - if(istype(P, /obj/item/stack/sheet/rglass)) - var/obj/item/stack/sheet/rglass/G = P - if(G.get_amount() >= 2) - playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) - user << "You start to put in the glass panel..." - if(do_after(user, 20, target = src)) - if (G.get_amount() >= 2 && state == 3) - G.use(2) + if(istype(P, /obj/item/stack/sheet/rglass)) + var/obj/item/stack/sheet/rglass/G = P + if(G.get_amount() >= 2) + playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) + user << "You start to put in the glass panel..." + if(do_after(user, 20, target = src) && state == CABLED_CORE && G.use(2)) user << "You put in the glass panel." - state = 4 + state = GLASS_CORE icon_state = "4" - else - user << "You need two sheets of reinforced glass to insert them into the AI core!" - return - - if(istype(P, /obj/item/weapon/aiModule)) - var/obj/item/weapon/aiModule/module = P - module.install(laws, user) - return - - if(istype(P, /obj/item/device/mmi)) - var/obj/item/device/mmi/M = P - if(!M.brainmob) - user << "Sticking an empty MMI into the frame would sort of defeat the purpose!" - return - if(M.brainmob.stat == DEAD) - user << "Sticking a dead brain into the frame would sort of defeat the purpose!" + else + user << "You need two sheets of reinforced glass to insert them into the AI core!" return - if(!M.brainmob.client) - user << "Sticking an inactive brain into the frame would sort of defeat the purpose." + if(istype(P, /obj/item/weapon/aiModule)) + var/obj/item/weapon/aiModule/module = P + module.install(laws, user) return - if((config) && (!config.allow_ai)) - user << "This MMI does not seem to fit!" - return + if(istype(P, /obj/item/device/mmi) && !brain) + var/obj/item/device/mmi/M = P + if(!M.brainmob) + user << "Sticking an empty MMI into the frame would sort of defeat the purpose!" + return + if(M.brainmob.stat == DEAD) + user << "Sticking a dead brain into the frame would sort of defeat the purpose!" + return - if(jobban_isbanned(M.brainmob, "AI")) - user << "This MMI does not seem to fit!" - return + if(!M.brainmob.client) + user << "Sticking an inactive brain into the frame would sort of defeat the purpose." + return - if(M.hacked || M.clockwork) - user << "This MMI does not seem to fit!" - return + if((config) && (!config.allow_ai) || jobban_isbanned(M.brainmob, "AI") || M.hacked || M.clockwork) + user << "This MMI does not seem to fit!" + return - if(!M.brainmob.mind) - user << "This MMI is mindless!" - return + if(!M.brainmob.mind) + user << "This MMI is mindless!" + return - if(!user.drop_item()) - return + if(!user.drop_item()) + return - ticker.mode.remove_antag_for_borging(M.brainmob.mind) - remove_servant_of_ratvar(M, TRUE) - M.loc = src - brain = M - user << "Added a brain." - icon_state = "3b" - return - - if(istype(P, /obj/item/weapon/crowbar) && brain) - playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) - user << "You remove the brain." - brain.forceMove(loc) - brain = null - icon_state = "3" - return - - if(4) - if(istype(P, /obj/item/weapon/crowbar)) - playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) - user << "You remove the glass panel." - state = 3 - if (brain) + ticker.mode.remove_antag_for_borging(M.brainmob.mind) + remove_servant_of_ratvar(M, TRUE) + M.forceMove(src) + brain = M + user << "Added a brain." icon_state = "3b" - else - icon_state = "3" - new /obj/item/stack/sheet/rglass(loc, 2) - return + return - if(istype(P, /obj/item/weapon/screwdriver)) - playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) - user << "You connect the monitor." - new /mob/living/silicon/ai (loc, laws, brain) - feedback_inc("cyborg_ais_created",1) - qdel(src) - return + if(istype(P, /obj/item/weapon/crowbar) && brain) + playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) + user << "You remove the brain." + brain.forceMove(loc) + brain = null + icon_state = "3" + return + + if(GLASS_CORE) + if(istype(P, /obj/item/weapon/crowbar)) + playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) + user << "You remove the glass panel." + state = CABLED_CORE + if(brain) + icon_state = "3b" + else + icon_state = "3" + new /obj/item/stack/sheet/rglass(loc, 2) + return + + if(istype(P, /obj/item/weapon/screwdriver)) + playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) + user << "You connect the monitor." + new /mob/living/silicon/ai (loc, laws, brain) + feedback_inc("cyborg_ais_created",1) + qdel(src) + return return ..() /obj/structure/AIcore/deconstruct(disassembled = TRUE) - if(state == 4) + if(state == GLASS_CORE) new /obj/item/stack/sheet/rglass(loc, 2) - if(state >= 3) + if(state >= CABLED_CORE) new /obj/item/stack/cable_coil(loc, 5) if(circuit) circuit.forceMove(loc) circuit = null - new /obj/item/stack/sheet/plasteel( loc, 4) + new /obj/item/stack/sheet/plasteel(loc, 4) qdel(src) /obj/structure/AIcore/deactivated @@ -219,24 +210,11 @@ icon = 'icons/mob/AI.dmi' icon_state = "ai-empty" anchored = 1 - state = 20//So it doesn't interact based on the above. Not really necessary. + state = GLASS_CORE /obj/structure/AIcore/deactivated/attackby(obj/item/A, mob/user, params) - if(istype(A, /obj/item/device/aicard))//Is it? + if(istype(A, /obj/item/device/aicard) && state == GLASS_CORE) A.transfer_ai("INACTIVE","AICARD",src,user) - else if(istype(A, /obj/item/weapon/wrench)) - playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) - user.visible_message("[user] [anchored ? "fastens" : "unfastens"] [src].", \ - "You start to [anchored ? "fasten [src] to" : "unfasten [src] from"] the floor...") - switch(anchored) - if(0) - if(do_after(user, 20, target = src)) - user << "You fasten the core into place." - anchored = 1 - if(1) - if(do_after(user, 20, target = src)) - user << "You unfasten the core." - anchored = 0 else return ..() @@ -248,7 +226,7 @@ That prevents a few funky behaviors. //The type of interaction, the player performing the operation, the AI itself, and the card object, if any. -atom/proc/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card) +/atom/proc/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card) if(istype(card)) if(card.flush) user << "ERROR: AI flush is in progress, cannot execute transfer protocol." diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 8e3fc4a8fff..492b9d022ae 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -18,6 +18,7 @@ var/list/ai_list = list() icon_state = "ai" anchored = 1 density = 1 + canmove = 0 status_flags = CANSTUN|CANPUSH a_intent = "harm" //so we always get pushed instead of trying to swap force_compose = 1 //This ensures that the AI always composes it's own hear message. Needed for hrefs and job display. @@ -80,12 +81,34 @@ var/list/ai_list = list() /mob/living/silicon/ai/New(loc, datum/ai_laws/L, obj/item/device/mmi/B, safety = 0) ..() + if(!safety) //Only used by AIize() to successfully spawn an AI. + if(!B) //If there is no player/brain inside. + new/obj/structure/AIcore/deactivated(loc) //New empty terminal. + qdel(src)//Delete AI. + return + else + if(B.brainmob.mind) + B.brainmob.mind.transfer_to(src) + rename_self("ai") + if(mind.special_role) + mind.store_memory("As an AI, you must obey your silicon laws above all else. Your objectives will consider you to be dead.") + src << "You have been installed as an AI! " + src << "You must obey your silicon laws above all else. Your objectives will consider you to be dead." + + src << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras)." + src << "To look at other parts of the station, click on yourself to get a camera menu." + src << "While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc." + src << "To use something, simply click on it." + src << "Use say :b to speak to your cyborgs through binary." + src << "For department channels, use the following say commands:" + src << ":o - AI Private, :c - Command, :s - Security, :e - Engineering, :u - Supply, :v - Service, :m - Medical, :n - Science." + show_laws() + src << "These laws may be changed by other players, or by you being the traitor." + + job = "AI" + rename_self("ai") name = real_name - anchored = 1 - canmove = 0 - density = 1 - loc = loc holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1")) @@ -116,31 +139,6 @@ var/list/ai_list = list() /mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall,\ /mob/living/silicon/ai/proc/control_integrated_radio, /mob/living/silicon/ai/proc/set_automatic_say_channel) - if(!safety)//Only used by AIize() to successfully spawn an AI. - if (!B)//If there is no player/brain inside. - new/obj/structure/AIcore/deactivated(loc)//New empty terminal. - qdel(src)//Delete AI. - return - else - if (B.brainmob.mind) - B.brainmob.mind.transfer_to(src) - rename_self("ai") - if(mind.special_role) - mind.store_memory("As an AI, you must obey your silicon laws above all else. Your objectives will consider you to be dead.") - src << "You have been installed as an AI! " - src << "You must obey your silicon laws above all else. Your objectives will consider you to be dead." - - src << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras)." - src << "To look at other parts of the station, click on yourself to get a camera menu." - src << "While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc." - src << "To use something, simply click on it." - src << "Use say :b to speak to your cyborgs through binary." - src << "For department channels, use the following say commands:" - src << ":o - AI Private, :c - Command, :s - Security, :e - Engineering, :u - Supply, :v - Service, :m - Medical, :n - Science." - show_laws() - src << "These laws may be changed by other players, or by you being the traitor." - - job = "AI" ai_list += src shuttle_caller_list += src @@ -333,7 +331,7 @@ var/list/ai_list = list() return //won't work if dead anchored = !anchored // Toggles the anchor - src << "[anchored ? "You are now anchored." : "You are now unanchored."]" + src << "You are now [anchored ? "" : "un"]anchored." // the message in the [] will change depending whether or not the AI is anchored /mob/living/silicon/ai/update_canmove() //If the AI dies, mobs won't go through it anymore