Files
Bubberstation/code/game/objects/structures/ai_core.dm
Mothblocks 0f435d5dff Remove hideous inline tab indentation, and bans it in contributing guidelines (#56912)
Done using this command sed -Ei 's/(\s*\S+)\s*\t+/\1 /g' code/**/*.dm

We have countless examples in the codebase with this style gone wrong, and defines and such being on hideously different levels of indentation. Fixing this to keep the alignment involves tainting the blames of code your PR doesn't need to be touching at all. And ultimately, it's hideous.

There are some files that this sed makes uglier. I can fix these when they are pointed out, but I believe this is ultimately for the greater good of readability. I'm more concerned with if any strings relied on this.

Hi codeowners!

Co-authored-by: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com>
2021-02-14 16:53:29 -08:00

330 lines
11 KiB
Plaintext

/obj/structure/ai_core
density = TRUE
anchored = FALSE
name = "\improper AI core"
icon = 'icons/mob/ai.dmi'
icon_state = "0"
desc = "The framework for an artificial intelligence core."
max_integrity = 500
var/state = EMPTY_CORE
var/datum/ai_laws/laws
var/obj/item/circuitboard/aicore/circuit
var/obj/item/mmi/brain
var/can_deconstruct = TRUE
/obj/structure/ai_core/Initialize()
. = ..()
laws = new
laws.set_laws_config()
/obj/structure/ai_core/handle_atom_del(atom/A)
if(A == circuit)
circuit = null
if((state != GLASS_CORE) && (state != AI_READY_CORE))
state = EMPTY_CORE
update_icon()
if(A == brain)
brain = null
return ..()
/obj/structure/ai_core/Destroy()
QDEL_NULL(circuit)
QDEL_NULL(brain)
QDEL_NULL(laws)
return ..()
/obj/structure/ai_core/deactivated
name = "inactive AI"
icon_state = "ai-empty"
anchored = TRUE
state = AI_READY_CORE
/obj/structure/ai_core/deactivated/Initialize()
. = ..()
circuit = new(src)
/obj/structure/ai_core/latejoin_inactive
name = "networked AI core"
desc = "This AI core is connected by bluespace transmitters to NTNet, allowing for an AI personality to be downloaded to it on the fly mid-shift."
can_deconstruct = FALSE
icon_state = "ai-empty"
anchored = TRUE
state = AI_READY_CORE
var/available = TRUE
var/safety_checks = TRUE
var/active = TRUE
/obj/structure/ai_core/latejoin_inactive/Initialize()
. = ..()
circuit = new(src)
GLOB.latejoin_ai_cores += src
/obj/structure/ai_core/latejoin_inactive/Destroy()
GLOB.latejoin_ai_cores -= src
return ..()
/obj/structure/ai_core/latejoin_inactive/examine(mob/user)
. = ..()
. += "Its transmitter seems to be <b>[active? "on" : "off"]</b>."
. += "<span class='notice'>You could [active? "deactivate" : "activate"] it with a multitool.</span>"
/obj/structure/ai_core/latejoin_inactive/proc/is_available() //If people still manage to use this feature to spawn-kill AI latejoins ahelp them.
if(!available)
return FALSE
if(!safety_checks)
return TRUE
if(!active)
return FALSE
var/turf/T = get_turf(src)
var/area/A = get_area(src)
if(!(A.area_flags & BLOBS_ALLOWED))
return FALSE
if(!A.power_equip)
return FALSE
if(!SSmapping.level_trait(T.z,ZTRAIT_STATION))
return FALSE
if(!istype(T, /turf/open/floor))
return FALSE
return TRUE
/obj/structure/ai_core/latejoin_inactive/attackby(obj/item/P, mob/user, params)
if(P.tool_behaviour == TOOL_MULTITOOL)
active = !active
to_chat(user, "<span class='notice'>You [active? "activate" : "deactivate"] \the [src]'s transmitters.</span>")
return
return ..()
/obj/structure/ai_core/attackby(obj/item/P, mob/user, params)
if(P.tool_behaviour == TOOL_WRENCH)
return default_unfasten_wrench(user, P, 20)
if(!anchored)
if(P.tool_behaviour == TOOL_WELDER && can_deconstruct)
if(state != EMPTY_CORE)
to_chat(user, "<span class='warning'>The core must be empty to deconstruct it!</span>")
return
if(!P.tool_start_check(user, amount=0))
return
to_chat(user, "<span class='notice'>You start to deconstruct the frame...</span>")
if(P.use_tool(src, user, 20, volume=50) && state == EMPTY_CORE)
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
deconstruct(TRUE)
return
else
switch(state)
if(EMPTY_CORE)
if(istype(P, /obj/item/circuitboard/aicore))
if(!user.transferItemToLoc(P, src))
return
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
to_chat(user, "<span class='notice'>You place the circuit board inside the frame.</span>")
update_icon()
state = CIRCUIT_CORE
circuit = P
return
if(CIRCUIT_CORE)
if(P.tool_behaviour == TOOL_SCREWDRIVER)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You screw the circuit board into place.</span>")
state = SCREWED_CORE
update_icon()
return
if(P.tool_behaviour == TOOL_CROWBAR)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the circuit board.</span>")
state = EMPTY_CORE
update_icon()
circuit.forceMove(loc)
circuit = null
return
if(SCREWED_CORE)
if(P.tool_behaviour == TOOL_SCREWDRIVER && circuit)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You unfasten the circuit board.</span>")
state = CIRCUIT_CORE
update_icon()
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, TRUE)
to_chat(user, "<span class='notice'>You start to add cables to the frame...</span>")
if(do_after(user, 20, target = src) && state == SCREWED_CORE && C.use(5))
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
state = CABLED_CORE
update_icon()
else
to_chat(user, "<span class='warning'>You need five lengths of cable to wire the AI core!</span>")
return
if(CABLED_CORE)
if(P.tool_behaviour == TOOL_WIRECUTTER)
if(brain)
to_chat(user, "<span class='warning'>Get that [brain.name] out of there first!</span>")
else
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the cables.</span>")
state = SCREWED_CORE
update_icon()
new /obj/item/stack/cable_coil(drop_location(), 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, TRUE)
to_chat(user, "<span class='notice'>You start to put in the glass panel...</span>")
if(do_after(user, 20, target = src) && state == CABLED_CORE && G.use(2))
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
state = GLASS_CORE
update_icon()
else
to_chat(user, "<span class='warning'>You need two sheets of reinforced glass to insert them into the AI core!</span>")
return
if(istype(P, /obj/item/ai_module))
if(brain && brain.laws.id != DEFAULT_AI_LAWID)
to_chat(user, "<span class='warning'>The installed [brain.name] already has set laws!</span>")
return
var/obj/item/ai_module/module = P
module.install(laws, user)
return
if(istype(P, /obj/item/mmi) && !brain)
var/obj/item/mmi/M = P
if(!M.brain_check(user))
return
var/mob/living/brain/B = M.brainmob
if(!CONFIG_GET(flag/allow_ai) || (is_banned_from(B.ckey, "AI") && !QDELETED(src) && !QDELETED(user) && !QDELETED(M) && !QDELETED(user) && Adjacent(user)))
if(!QDELETED(M))
to_chat(user, "<span class='warning'>This [M.name] does not seem to fit!</span>")
return
if(!user.transferItemToLoc(M,src))
return
brain = M
to_chat(user, "<span class='notice'>You add [M.name] to the frame.</span>")
update_icon()
return
if(P.tool_behaviour == TOOL_CROWBAR && brain)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the brain.</span>")
brain.forceMove(loc)
brain = null
update_icon()
return
if(GLASS_CORE)
if(P.tool_behaviour == TOOL_CROWBAR)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
state = CABLED_CORE
update_icon()
new /obj/item/stack/sheet/rglass(loc, 2)
return
if(P.tool_behaviour == TOOL_SCREWDRIVER)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
if(brain)
var/mob/living/brain/B = brain.brainmob
SSticker.mode.remove_antag_for_borging(B.mind)
var/mob/living/silicon/ai/A = null
if (brain.overrides_aicore_laws)
A = new /mob/living/silicon/ai(loc, brain.laws, B)
brain.laws = null //Brain's law datum is being donated, so we need the brain to let it go or the GC will eat it
else
A = new /mob/living/silicon/ai(loc, laws, B)
laws = null //we're giving the new AI this datum, so let's not delete it when we qdel(src) 5 lines from now
if(brain.force_replace_ai_name)
A.fully_replace_character_name(A.name, brain.replacement_ai_name())
SSblackbox.record_feedback("amount", "ais_created", 1)
deadchat_broadcast(" has been brought online at <b>[get_area_name(A, TRUE)]</b>.", "<span class='name'>[A]</span>", follow_target=A, message_type=DEADCHAT_ANNOUNCEMENT)
qdel(src)
else
state = AI_READY_CORE
update_icon()
return
if(AI_READY_CORE)
if(istype(P, /obj/item/aicard))
return //handled by /obj/structure/ai_core/transfer_ai()
if(P.tool_behaviour == TOOL_SCREWDRIVER)
P.play_tool_sound(src)
to_chat(user, "<span class='notice'>You disconnect the monitor.</span>")
state = GLASS_CORE
update_icon()
return
return ..()
/obj/structure/ai_core/update_icon_state()
switch(state)
if(EMPTY_CORE)
icon_state = "0"
if(CIRCUIT_CORE)
icon_state = "1"
if(SCREWED_CORE)
icon_state = "2"
if(CABLED_CORE)
if(brain)
icon_state = "3b"
else
icon_state = "3"
if(GLASS_CORE)
icon_state = "4"
if(AI_READY_CORE)
icon_state = "ai-empty"
/obj/structure/ai_core/deconstruct(disassembled = TRUE)
if(state == GLASS_CORE)
new /obj/item/stack/sheet/rglass(loc, 2)
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)
qdel(src)
/*
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.
*/
//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/aicard/card)
if(istype(card))
if(card.flush)
to_chat(user, "<span class='alert'>ERROR: AI flush is in progress, cannot execute transfer protocol.</span>")
return FALSE
return TRUE
/obj/structure/ai_core/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card)
if(state != AI_READY_CORE || !..())
return
//Transferring a carded AI to a core.
if(interaction == AI_TRANS_FROM_CARD)
AI.control_disabled = FALSE
AI.radio_enabled = TRUE
AI.forceMove(loc) // to replace the terminal.
to_chat(AI, "<span class='notice'>You have been uploaded to a stationary terminal. Remote device connection restored.</span>")
to_chat(user, "<span class='boldnotice'>Transfer successful</span>: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.")
card.AI = null
AI.battery = circuit.battery
qdel(src)
else //If for some reason you use an empty card on an empty AI terminal.
to_chat(user, "<span class='alert'>There is no AI loaded on this terminal.</span>")
/obj/item/circuitboard/aicore
name = "AI core (AI Core Board)" //Well, duh, but best to be consistent
var/battery = 200 //backup battery for when the AI loses power. Copied to/from AI mobs when carding, and placed here to avoid recharge via deconning the core