diff --git a/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm b/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm index 45ec61e3646d..3d3c2a4e4e1b 100644 --- a/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm +++ b/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm @@ -3126,12 +3126,6 @@ /obj/structure/cable/smart_cable/color/yellow, /turf/open/floor/iron/airless, /area/ruin/space/derelict/bridge/ai_upload) -"LG" = ( -/obj/item/aicard, -/obj/structure/cable/smart_cable/color/yellow, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/iron/airless, -/area/ruin/space/derelict/bridge/ai_upload) "LX" = ( /obj/machinery/power/smes/engineering{ charge = 0 @@ -9425,7 +9419,7 @@ bj ax bK GD -LG +GD am YQ ax diff --git a/_maps/RandomRuins/SpaceRuins/abandonedteleporter.dmm b/_maps/RandomRuins/SpaceRuins/abandonedteleporter.dmm index 0f5ffbcb72c7..570100380483 100644 --- a/_maps/RandomRuins/SpaceRuins/abandonedteleporter.dmm +++ b/_maps/RandomRuins/SpaceRuins/abandonedteleporter.dmm @@ -111,7 +111,6 @@ /area/ruin/space/abandoned_tele) "z" = ( /obj/structure/closet/crate, -/obj/item/aicard, /obj/item/multitool, /obj/item/weldingtool, /obj/item/wrench, diff --git a/_maps/map_files/Theseus/Theseus.dmm b/_maps/map_files/Theseus/Theseus.dmm index 5712c1ac7d40..c1a9964caec9 100644 --- a/_maps/map_files/Theseus/Theseus.dmm +++ b/_maps/map_files/Theseus/Theseus.dmm @@ -654,6 +654,16 @@ /obj/structure/overfloor_catwalk/iron_dark, /turf/open/floor/plating, /area/station/maintenance/port) +"ajV" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable/cyan{ + icon_state = "3" + }, +/obj/machinery/ai_slipper{ + uses = 10 + }, +/turf/open/floor/iron/dark, +/area/station/ai_monitored/turret_protected/ai) "ajX" = ( /obj/structure/window/reinforced/spawner/west, /obj/structure/lattice/catwalk, @@ -2630,6 +2640,8 @@ /obj/machinery/porta_turret/ai{ dir = 4 }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/status_display/ai/directional/west, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "aVq" = ( @@ -2641,6 +2653,8 @@ /obj/machinery/porta_turret/ai{ dir = 8 }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/status_display/ai/directional/east, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "aVt" = ( @@ -2753,7 +2767,7 @@ /turf/open/floor/iron/ported/techfloor_grid, /area/station/engineering/supermatter/room) "aWN" = ( -/turf/open/floor/circuit, +/turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "aWT" = ( /obj/effect/turf_decal/stripes/line{ @@ -3123,7 +3137,7 @@ /obj/structure/cable/cyan{ icon_state = "12" }, -/turf/open/floor/circuit, +/turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "beX" = ( /obj/structure/disposalpipe/segment{ @@ -3640,6 +3654,13 @@ "bnW" = ( /turf/open/floor/iron/dark, /area/station/command/bridge) +"bnZ" = ( +/obj/machinery/porta_turret/ai{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/ai_monitored/turret_protected/ai) "bon" = ( /obj/machinery/power/terminal{ dir = 1 @@ -4079,12 +4100,6 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron/freezer, /area/station/commons/toilet/restrooms) -"bvw" = ( -/obj/structure/showcase/cyborg/old{ - pixel_y = 20 - }, -/turf/open/floor/iron/grimy, -/area/station/tcommsat/computer) "bvB" = ( /obj/item/kirbyplants{ icon_state = "plant-20" @@ -9131,20 +9146,6 @@ /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/carpet, /area/station/commons/dorms) -"dor" = ( -/obj/effect/spawner/structure/window/reinforced/prepainted/daedalus, -/obj/machinery/door/poddoor/shutters/preopen{ - name = "AI core shutters"; - id = "AI Core shutters" - }, -/obj/structure/cable/red{ - icon_state = "3" - }, -/obj/structure/cable/red{ - icon_state = "1" - }, -/turf/open/floor/plating, -/area/station/ai_monitored/turret_protected/ai) "dot" = ( /obj/structure/chair/comfy/brown{ dir = 1 @@ -13813,22 +13814,6 @@ /obj/effect/mapping_helpers/airlock/access/all/medical/general, /turf/open/floor/iron/white, /area/station/medical/virology) -"eZP" = ( -/obj/machinery/door/window{ - name = "Primary AI Core Access"; - icon_state = "rightsecure"; - dir = 4; - atom_integrity = 300; - base_state = "rightsecure"; - req_access_txt = "16" - }, -/obj/machinery/camera/directional/north{ - network = list("aicore"); - c_tag = "AI Chamber - Core" - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/ai_monitored/turret_protected/ai) "eZV" = ( /obj/effect/turf_decal/stripes/corner, /obj/structure/cable/yellow{ @@ -14087,6 +14072,13 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 }, +/obj/machinery/turretid{ + name = "AI Chamber turret control"; + icon_state = "control_stun"; + pixel_x = 3; + pixel_y = -23 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "ffx" = ( @@ -15435,15 +15427,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/commons/lounge) -"fKn" = ( -/obj/machinery/flasher/directional/east{ - pixel_y = 26; - id = "AI" - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/machinery/holopad/secure, -/turf/open/floor/iron/dark, -/area/station/ai_monitored/turret_protected/ai) "fKp" = ( /turf/closed/wall/prepainted/daedalus, /area/station/security/prison/shower) @@ -16682,12 +16665,6 @@ network = list("aicore"); c_tag = "AI Chamber - Starboard" }, -/obj/structure/showcase/cyborg/old{ - dir = 8; - pixel_x = 9; - pixel_y = 2 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "gjD" = ( @@ -17058,6 +17035,7 @@ /obj/structure/cable/cyan{ icon_state = "10" }, +/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "grZ" = ( @@ -17632,6 +17610,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) +"gAv" = ( +/obj/machinery/porta_turret/ai{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/ai_monitored/turret_protected/ai) "gAB" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{ dir = 4 @@ -19271,9 +19256,6 @@ /turf/open/floor/iron, /area/station/service/hydroponics) "hfN" = ( -/obj/structure/showcase/cyborg/old{ - pixel_y = 20 - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -20795,7 +20777,7 @@ /obj/structure/cable/cyan{ icon_state = "3" }, -/turf/open/floor/circuit, +/turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "hON" = ( /obj/structure/sign/map/left{ @@ -21250,6 +21232,7 @@ "hXC" = ( /obj/machinery/status_display/evac/directional/north, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "hXD" = ( @@ -22947,7 +22930,8 @@ /area/station/medical/virology) "iCV" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/circuit, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "iCY" = ( /obj/structure/table, @@ -23464,17 +23448,8 @@ /turf/open/floor/iron, /area/station/security/checkpoint/customs) "iOn" = ( -/obj/machinery/ai_slipper{ - uses = 10 - }, -/obj/machinery/flasher/directional/south{ - pixel_x = 26; - id = "AI" - }, /obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/structure/cable/red{ - icon_state = "9" - }, +/obj/machinery/holopad/secure, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "iOp" = ( @@ -24003,8 +23978,7 @@ /area/station/maintenance/port/aft) "iZN" = ( /obj/machinery/light/directional/east, -/obj/machinery/status_display/ai/directional/east, -/turf/open/floor/circuit, +/turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "iZR" = ( /obj/structure/toilet{ @@ -25161,36 +25135,10 @@ /turf/open/floor/wood, /area/station/hallway/secondary/exit) "jug" = ( -/obj/effect/landmark/start/ai/secondary, -/obj/item/radio/intercom/directional/north{ - name = "Custom Channel"; - pixel_x = -8; - listening = 0; - freerange = 1 - }, -/obj/item/radio/intercom/directional/west{ - name = "Common Channel"; - listening = 0; - freerange = 1 - }, -/obj/item/radio/intercom/directional/south{ - name = "Private Channel"; - pixel_x = -8; - frequency = 1447; - listening = 0; - freerange = 1 - }, -/obj/machinery/door/window{ - name = "Secondary AI Core Access"; - icon_state = "rightsecure"; - dir = 4; - layer = 4.1; - pixel_x = 4; - atom_integrity = 300; - base_state = "rightsecure"; - req_access_txt = "16" +/obj/machinery/power/smes{ + charge = 1e+07 }, -/turf/open/floor/circuit/green, +/turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "juZ" = ( /obj/machinery/door/firedoor, @@ -26423,40 +26371,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/port) -"jUG" = ( -/obj/item/radio/intercom/directional/west{ - name = "Common Channel"; - pixel_y = -8; - listening = 0; - freerange = 1 - }, -/obj/item/radio/intercom/directional/south{ - name = "Private Channel"; - frequency = 1447; - listening = 0; - freerange = 1 - }, -/obj/item/radio/intercom/directional/east{ - name = "Custom Channel"; - pixel_y = -8; - listening = 0; - freerange = 1 - }, -/obj/effect/landmark/start/ai, -/obj/machinery/button/door/directional/south{ - name = "AI Chamber Entrance Shutters Control"; - pixel_x = -24; - id = "AI Chamber entrance shutters"; - req_access_txt = "16" - }, -/obj/machinery/button/door/directional/south{ - name = "AI Core Shutters Control"; - pixel_x = 24; - id = "AI Core shutters"; - req_access_txt = "16" - }, -/turf/open/floor/circuit/green, -/area/station/ai_monitored/turret_protected/ai) "jUK" = ( /obj/effect/decal/cleanable/dirt, /turf/closed/wall/prepainted/daedalus, @@ -26468,15 +26382,12 @@ /turf/open/floor/engine/airless, /area/station/engineering/supermatter/room) "jVh" = ( -/obj/machinery/ai_slipper{ - uses = 10 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable/cyan{ icon_state = "6" }, -/turf/open/floor/circuit, +/turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "jVp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -28180,12 +28091,7 @@ /turf/open/floor/iron/ported/techfloor_grid, /area/station/engineering/supermatter/room) "kBT" = ( -/obj/structure/showcase/cyborg/old{ - pixel_y = 20 - }, -/obj/structure/cable/red{ - icon_state = "48" - }, +/obj/structure/ai_fluff/brad, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "kBZ" = ( @@ -29066,9 +28972,6 @@ /turf/open/floor/carpet, /area/station/command/heads_quarters/captain/private) "kTN" = ( -/obj/structure/showcase/cyborg/old{ - pixel_y = 20 - }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, @@ -30447,12 +30350,7 @@ /turf/open/floor/iron/white, /area/station/medical/virology) "lro" = ( -/obj/structure/showcase/cyborg/old{ - dir = 4; - pixel_x = -9; - pixel_y = 2 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/power/apc/auto_name/directional/west, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "lrq" = ( @@ -32117,7 +32015,6 @@ /area/station/maintenance/port/fore) "lZB" = ( /obj/structure/table, -/obj/item/aicard, /obj/item/ai_module/reset, /turf/open/floor/iron/dark, /area/station/engineering/storage/tech) @@ -36258,11 +36155,8 @@ /turf/open/floor/iron, /area/station/hallway/primary/central/starboard) "nxW" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/machinery/holopad/secure, -/obj/machinery/flasher/directional/west{ - pixel_y = -26; - id = "AI" +/obj/machinery/power/terminal{ + dir = 8 }, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) @@ -36811,13 +36705,6 @@ /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible, /turf/closed/wall/prepainted/daedalus, /area/station/engineering/atmos/pumproom) -"nHn" = ( -/obj/machinery/ai_slipper{ - uses = 10 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/circuit, -/area/station/ai_monitored/turret_protected/ai) "nHo" = ( /obj/machinery/power/apc/auto_name/directional/south, /obj/structure/disposalpipe/segment{ @@ -37087,13 +36974,11 @@ network = list("aicore"); c_tag = "AI Chamber - Fore" }, -/obj/structure/showcase/cyborg/old{ - pixel_y = 20 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable/cyan{ icon_state = "12" }, +/obj/structure/ai_fluff, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "nMh" = ( @@ -37899,8 +37784,7 @@ /area/station/service/hydroponics) "odP" = ( /obj/machinery/light/directional/west, -/obj/machinery/status_display/ai/directional/west, -/turf/open/floor/circuit, +/turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "oee" = ( /obj/machinery/status_display/evac/directional/west, @@ -38093,14 +37977,8 @@ /turf/open/floor/iron, /area/station/security/medical) "ohJ" = ( -/obj/machinery/power/smes{ - charge = 1e+07 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable/red{ - icon_state = "128" - }, -/turf/open/floor/iron/dark, +/turf/closed/wall/r_wall/prepainted/daedalus, /area/station/ai_monitored/turret_protected/ai) "ohL" = ( /obj/effect/decal/cleanable/dirt, @@ -39228,15 +39106,6 @@ }, /turf/open/floor/iron, /area/station/security/prison/garden) -"oDc" = ( -/obj/structure/showcase/cyborg/old{ - dir = 8; - pixel_x = 9; - pixel_y = 2 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/ai_monitored/turret_protected/ai) "oDe" = ( /obj/structure/lattice/catwalk, /obj/structure/transit_tube/crossing/horizontal, @@ -39381,11 +39250,6 @@ /obj/machinery/field/generator, /turf/open/floor/plating, /area/station/engineering/main) -"oFC" = ( -/obj/machinery/status_display/ai/directional/west, -/obj/machinery/light/directional/west, -/turf/open/floor/circuit, -/area/station/ai_monitored/turret_protected/ai) "oFG" = ( /obj/machinery/light/cold/directional/south, /obj/machinery/firealarm/directional/south, @@ -40264,6 +40128,10 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/dark/telecomms, /area/station/tcommsat/server) +"oXB" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/ai_monitored/turret_protected/ai) "oXF" = ( /obj/structure/cable/yellow{ icon_state = "3" @@ -44639,9 +44507,6 @@ /area/station/security/courtroom) "qFO" = ( /obj/machinery/light_switch/directional/north, -/obj/structure/showcase/cyborg/old{ - pixel_y = 20 - }, /turf/open/floor/iron/grimy, /area/station/tcommsat/computer) "qFP" = ( @@ -47750,7 +47615,6 @@ /area/station/ai_monitored/security/armory) "rOb" = ( /obj/structure/rack, -/obj/item/aicard, /obj/item/radio/off, /obj/machinery/computer/security/telescreen/minisat{ dir = 1; @@ -48326,11 +48190,9 @@ /turf/open/floor/plating, /area/station/maintenance/solars/port/fore) "rYA" = ( -/obj/machinery/porta_turret/ai, -/obj/machinery/flasher/directional/north{ - id = "AI" +/obj/machinery/ai_slipper{ + uses = 10 }, -/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "rYU" = ( @@ -48549,28 +48411,6 @@ /obj/machinery/atmospherics/pipe/layer_manifold/yellow/visible, /turf/open/floor/iron/dark, /area/station/engineering/atmos) -"sdh" = ( -/obj/machinery/turretid{ - name = "AI Chamber turret control"; - icon_state = "control_stun"; - pixel_x = 3; - pixel_y = -23 - }, -/obj/machinery/door/window{ - name = "Primary AI Core Access"; - icon_state = "leftsecure"; - dir = 8; - atom_integrity = 300; - base_state = "leftsecure"; - req_access_txt = "16" - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable/red{ - icon_state = "4" - }, -/turf/open/floor/iron/dark, -/area/station/ai_monitored/turret_protected/ai) "sdl" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -48962,17 +48802,32 @@ /turf/open/floor/iron, /area/station/hallway/primary/fore) "sjZ" = ( -/obj/machinery/power/terminal{ - dir = 1 - }, -/obj/machinery/flasher/directional/north{ - pixel_x = -22; - id = "AI" - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable/cyan{ icon_state = "4" }, +/obj/effect/landmark/start/ai, +/obj/item/radio/intercom/directional/east{ + name = "Private Channel"; + frequency = 1447; + listening = 0; + broadcasting = 1; + pixel_x = -26; + pixel_y = -26 + }, +/obj/item/radio/intercom/directional/east{ + name = "Common Channel"; + listening = 0; + freerange = 1; + pixel_x = 0; + pixel_y = -26 + }, +/obj/item/radio/intercom/directional/east{ + name = "Custom Channel"; + pixel_y = -26; + listening = 0; + freerange = 1 + }, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "ska" = ( @@ -51183,15 +51038,6 @@ /obj/structure/window/reinforced/spawner/east, /turf/open/floor/iron, /area/station/security/checkpoint/customs) -"sZI" = ( -/obj/machinery/ai_slipper{ - uses = 10 - }, -/obj/structure/cable/red{ - icon_state = "66" - }, -/turf/open/floor/circuit, -/area/station/ai_monitored/turret_protected/ai) "sZX" = ( /obj/effect/turf_decal/tile/yellow{ dir = 8 @@ -51564,10 +51410,6 @@ /obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) -"tfz" = ( -/obj/machinery/airalarm/directional/north, -/turf/open/floor/circuit, -/area/station/ai_monitored/turret_protected/ai) "tfM" = ( /obj/machinery/firealarm/directional/north, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -53393,12 +53235,7 @@ network = list("aicore"); c_tag = "AI Chamber - Port" }, -/obj/structure/showcase/cyborg/old{ - dir = 4; - pixel_x = -9; - pixel_y = 2 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/airalarm/directional/west, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "tRC" = ( @@ -55224,38 +55061,6 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/secondary/exit) -"uAj" = ( -/obj/effect/landmark/start/ai/secondary, -/obj/item/radio/intercom/directional/north{ - name = "Custom Channel"; - pixel_x = 8; - listening = 0; - freerange = 1 - }, -/obj/item/radio/intercom/directional/east{ - name = "Common Channel"; - listening = 0; - freerange = 1 - }, -/obj/item/radio/intercom/directional/south{ - name = "Private Channel"; - pixel_x = 8; - frequency = 1447; - listening = 0; - freerange = 1 - }, -/obj/machinery/door/window{ - name = "Tertiary AI Core Access"; - icon_state = "leftsecure"; - dir = 8; - layer = 4.1; - pixel_x = -3; - atom_integrity = 300; - base_state = "leftsecure"; - req_access_txt = "16" - }, -/turf/open/floor/circuit/green, -/area/station/ai_monitored/turret_protected/ai) "uAl" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -55445,16 +55250,6 @@ /obj/structure/sign/poster/contraband/random/directional/east, /turf/open/floor/wood, /area/station/service/theater) -"uEH" = ( -/obj/machinery/ai_slipper{ - uses = 10 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable/cyan{ - icon_state = "3" - }, -/turf/open/floor/circuit, -/area/station/ai_monitored/turret_protected/ai) "uEI" = ( /obj/machinery/door/firedoor, /obj/effect/landmark/navigate_destination, @@ -55937,6 +55732,7 @@ /obj/structure/cable/yellow{ icon_state = "144" }, +/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "uNA" = ( @@ -56264,7 +56060,10 @@ /area/station/maintenance/port/greater) "uUX" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/circuit, +/obj/machinery/ai_slipper{ + uses = 10 + }, +/turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) "uUZ" = ( /obj/machinery/holopad, @@ -59207,12 +59006,6 @@ pixel_x = 5; pixel_y = -1 }, -/obj/item/radio/intercom/directional/east{ - name = "Private Channel"; - frequency = 1447; - listening = 0; - broadcasting = 1 - }, /obj/machinery/telephone/security, /obj/machinery/power/data_terminal, /obj/structure/cable/yellow{ @@ -120661,8 +120454,8 @@ aaa aaa cTo sqf -aVl -oFC +bnZ +odP tRv nxW lro @@ -120919,12 +120712,12 @@ cTo cTo sqf hXC +azv +azv +azv uUX -uUX -nHn -uUX -uUX -uUX +azv +azv azv dKG aAp @@ -121176,13 +120969,13 @@ cTo cTo sqf kBT +oXB aWN -sqf -sdh -sqf -sqf aWN -uUX +aWN +aWN +aWN +azv ffv aAp hfN @@ -121190,7 +120983,7 @@ esU tMH bsb uBD -bvw +bxq yex bxq bJh @@ -121433,11 +121226,11 @@ lzc lzc ohJ sjZ -sZI -dor +oXB +rYA iOn -jUG -sqf +aWN +aWN rYA jVh aKb @@ -121691,11 +121484,11 @@ cTo sqf nMc iCV -sqf -eZP -sqf -sqf -tfz +aWN +aWN +aWN +aWN +aWN beK uNc aAp @@ -121949,8 +121742,8 @@ sqf grP hOq hOq -uEH hOq +ajV hOq hOq dAN @@ -122203,10 +121996,10 @@ aaa aaa cTo sqf -aVr +gAv iZN -oDc -fKn +aWN +aWN gjC iZN aVr @@ -122463,7 +122256,7 @@ cTo sqf sqf sqf -uAj +sqf sqf sqf sqf diff --git a/_maps/multiz_debug.json b/_maps/multiz_debug.json index 4ffc3abd519e..eaa71b7e2208 100644 --- a/_maps/multiz_debug.json +++ b/_maps/multiz_debug.json @@ -11,12 +11,12 @@ { "Up": 1, "Down": -1, - "Baseturf": "/turf/open/space/openspace", + "Baseturf": "/turf/open/openspace", "Linkage": "Cross" }, { "Down": -1, - "Baseturf": "/turf/open/space/openspace", + "Baseturf": "/turf/open/openspace", "Linkage": "Cross" } ] diff --git a/_maps/shuttles/emergency_cere.dmm b/_maps/shuttles/emergency_cere.dmm index 2b9d0ee8ae93..e38da5492ac6 100644 --- a/_maps/shuttles/emergency_cere.dmm +++ b/_maps/shuttles/emergency_cere.dmm @@ -1143,11 +1143,6 @@ }, /turf/open/floor/iron/white, /area/shuttle/escape) -"kk" = ( -/obj/machinery/computer/aifixer, -/obj/effect/turf_decal/tile/purple/fourcorners, -/turf/open/floor/iron/dark, -/area/shuttle/escape) "ok" = ( /obj/structure/table, /obj/item/storage/medkit/regular{ @@ -1543,7 +1538,7 @@ dz aa aa ac -kk +DS PD ap aI diff --git a/_maps/shuttles/emergency_cruise.dmm b/_maps/shuttles/emergency_cruise.dmm index 2333334989ff..bb215a69ca06 100644 --- a/_maps/shuttles/emergency_cruise.dmm +++ b/_maps/shuttles/emergency_cruise.dmm @@ -746,9 +746,6 @@ "FR" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue, -/obj/machinery/computer/aifixer{ - dir = 4 - }, /obj/effect/turf_decal/tile/purple{ dir = 8 }, diff --git a/_maps/shuttles/emergency_raven.dmm b/_maps/shuttles/emergency_raven.dmm index 18be85732e48..2257b52b8cf5 100644 --- a/_maps/shuttles/emergency_raven.dmm +++ b/_maps/shuttles/emergency_raven.dmm @@ -50,7 +50,6 @@ /area/shuttle/escape) "ai" = ( /obj/effect/turf_decal/bot_white, -/obj/machinery/computer/aifixer, /turf/open/floor/iron/dark, /area/shuttle/escape) "aj" = ( diff --git a/_maps/shuttles/infiltrator_basic.dmm b/_maps/shuttles/infiltrator_basic.dmm index a4fdebbc865d..0daed21a0875 100644 --- a/_maps/shuttles/infiltrator_basic.dmm +++ b/_maps/shuttles/infiltrator_basic.dmm @@ -62,7 +62,6 @@ req_access_txt = "150"; pixel_y = 24 }, -/obj/item/aicard, /obj/structure/table/reinforced/plastitaniumglass, /turf/open/floor/iron/dark, /area/shuttle/syndicate/bridge) @@ -918,9 +917,6 @@ "DP" = ( /obj/machinery/light/directional/east, /obj/effect/turf_decal/tile/red, -/obj/machinery/computer/aifixer{ - dir = 8 - }, /turf/open/floor/iron/dark, /area/shuttle/syndicate/bridge) "Ed" = ( diff --git a/_maps/templates/battlecruiser_starfury.dmm b/_maps/templates/battlecruiser_starfury.dmm index 7abed57e0ffd..0b2953bf7c08 100644 --- a/_maps/templates/battlecruiser_starfury.dmm +++ b/_maps/templates/battlecruiser_starfury.dmm @@ -443,7 +443,6 @@ /area/shuttle/sbc_starfury) "bq" = ( /obj/structure/table/reinforced, -/obj/item/aicard, /obj/structure/window/reinforced/survival_pod{ dir = 4 }, diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index c6fab7e2e4e7..88522648beaf 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -37,14 +37,6 @@ #define FAILED_UNFASTEN 1 #define SUCCESSFUL_UNFASTEN 2 -//ai core defines -#define EMPTY_CORE 0 -#define CIRCUIT_CORE 1 -#define SCREWED_CORE 2 -#define CABLED_CORE 3 -#define GLASS_CORE 4 -#define AI_READY_CORE 5 - //Construction defines for the pinion airlock #define GEAR_SECURE 1 #define GEAR_LOOSE 2 diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm index d4fd44c293c0..9ac0af5ea44c 100644 --- a/code/__DEFINES/robots.dm +++ b/code/__DEFINES/robots.dm @@ -20,12 +20,8 @@ #define AI_NOTIFICATION_CYBORG_DISCONNECTED 5 //transfer_ai() defines. Main proc in ai_core.dm -///Downloading AI to InteliCard -#define AI_TRANS_TO_CARD 1 -///Uploading AI from InteliCard -#define AI_TRANS_FROM_CARD 2 ///Malfunctioning AI hijacking mecha -#define AI_MECH_HACK 3 +#define AI_MECH_HACK 1 /** Cyborg defines */ diff --git a/code/datums/components/crafting/recipes.dm b/code/datums/components/crafting/recipes.dm index eace4fbd2ff9..0efacb338105 100644 --- a/code/datums/components/crafting/recipes.dm +++ b/code/datums/components/crafting/recipes.dm @@ -617,34 +617,6 @@ tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER) category = CAT_MISC -/datum/crafting_recipe/aitater - name = "intelliTater" - result = /obj/item/aicard/aitater - time = 30 - tool_behaviors = list(TOOL_WIRECUTTER) - reqs = list(/obj/item/aicard = 1, - /obj/item/food/grown/potato = 1, - /obj/item/stack/cable_coil = 5) - category = CAT_MISC - -/datum/crafting_recipe/aitater/check_requirements(mob/user, list/collected_requirements) - var/obj/item/aicard/aicard = collected_requirements[/obj/item/aicard][1] - if(!aicard.AI) - return TRUE - - to_chat(user, span_boldwarning("You can't craft an intelliTater with an AI in the card!")) - return FALSE - -/datum/crafting_recipe/aispook - name = "intelliLantern" - result = /obj/item/aicard/aispook - time = 30 - tool_behaviors = list(TOOL_WIRECUTTER) - reqs = list(/obj/item/aicard = 1, - /obj/item/food/grown/pumpkin = 1, - /obj/item/stack/cable_coil = 5) - category = CAT_MISC - /datum/crafting_recipe/ghettojetpack name = "Improvised Jetpack" result = /obj/item/tank/jetpack/improvised diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm deleted file mode 100644 index a8c9e5bed817..000000000000 --- a/code/game/machinery/computer/aifixer.dm +++ /dev/null @@ -1,141 +0,0 @@ -/obj/machinery/computer/aifixer - name = "\improper AI system integrity restorer" - desc = "Used with intelliCards containing nonfunctional AIs to restore them to working order." - req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_MANAGEMENT) - circuit = /obj/item/circuitboard/computer/aifixer - icon_keyboard = "tech_key" - icon_screen = "ai-fixer" - light_color = LIGHT_COLOR_PINK - - /// Variable containing transferred AI - var/mob/living/silicon/ai/occupier - /// Variable dictating if we are in the process of restoring the occupier AI - var/restoring = FALSE - -/obj/machinery/computer/aifixer/screwdriver_act(mob/living/user, obj/item/I) - if(occupier) - if(machine_stat & (NOPOWER|BROKEN)) - to_chat(user, span_warning("The screws on [name]'s screen won't budge.")) - else - to_chat(user, span_warning("The screws on [name]'s screen won't budge and it emits a warning beep.")) - else - return ..() - -/obj/machinery/computer/aifixer/ui_interact(mob/user, datum/tgui/ui) - . = ..() - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "AiRestorer", name) - ui.open() - -/obj/machinery/computer/aifixer/ui_data(mob/user) - var/list/data = list() - - data["ejectable"] = FALSE - data["AI_present"] = FALSE - data["error"] = null - if(!occupier) - data["error"] = "Please transfer an AI unit." - else - data["AI_present"] = TRUE - data["name"] = occupier.name - data["restoring"] = restoring - data["health"] = (occupier.health + 100) / 2 - data["isDead"] = occupier.stat == DEAD - data["laws"] = occupier.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE) - - return data - -/obj/machinery/computer/aifixer/ui_act(action, params) - . = ..() - if(.) - return - - if(!occupier) - restoring = FALSE - - switch(action) - if("PRG_beginReconstruction") - if(occupier?.health < 100) - to_chat(usr, span_notice("Reconstruction in progress. This will take several minutes.")) - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, FALSE) - restoring = TRUE - occupier.notify_ghost_revival("Your core files are being restored!", source = src) - . = TRUE - -/obj/machinery/computer/aifixer/proc/Fix() - use_power(1000) - occupier.adjustOxyLoss(-5, FALSE) - occupier.adjustFireLoss(-5, FALSE) - occupier.adjustBruteLoss(-5, FALSE) - occupier.updatehealth() - if(occupier.health >= 0 && occupier.stat == DEAD) - occupier.revive(full_heal = FALSE, admin_revive = FALSE) - if(!occupier.radio_enabled) - occupier.radio_enabled = TRUE - to_chat(occupier, span_warning("Your Subspace Transceiver has been enabled!")) - return occupier.health < 100 - -/obj/machinery/computer/aifixer/process() - if(..()) - if(restoring) - var/oldstat = occupier.stat - restoring = Fix() - if(oldstat != occupier.stat) - update_appearance() - -/obj/machinery/computer/aifixer/update_overlays() - . = ..() - if(machine_stat & (NOPOWER|BROKEN)) - return - - if(restoring) - . += "ai-fixer-on" - - if(!occupier) - . += "ai-fixer-empty" - return - switch(occupier.stat) - if(CONSCIOUS) - . += "ai-fixer-full" - if(UNCONSCIOUS) - . += "ai-fixer-404" - -/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) - if(!..()) - return - //Downloading AI from card to terminal. - if(interaction == AI_TRANS_FROM_CARD) - if(machine_stat & (NOPOWER|BROKEN)) - to_chat(user, span_alert("[src] is offline and cannot take an AI at this time.")) - return - AI.forceMove(src) - occupier = AI - AI.control_disabled = TRUE - AI.radio_enabled = FALSE - to_chat(AI, span_alert("You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.")) - to_chat(user, "[span_notice("Transfer successful")]: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") - card.AI = null - update_appearance() - - else //Uploading AI from terminal to card - if(occupier && !restoring) - to_chat(occupier, span_notice("You have been downloaded to a mobile storage device. Still no remote access.")) - to_chat(user, "[span_notice("Transfer successful")]: [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.") - occupier.forceMove(card) - card.AI = occupier - occupier = null - update_appearance() - else if (restoring) - to_chat(user, span_alert("ERROR: Reconstruction in progress.")) - else if (!occupier) - to_chat(user, span_alert("ERROR: Unable to locate artificial intelligence.")) - -/obj/machinery/computer/aifixer/Destroy() - if(occupier) - QDEL_NULL(occupier) - return ..() - -/obj/machinery/computer/aifixer/on_deconstruction() - if(occupier) - QDEL_NULL(occupier) diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index bd1d8ef83cea..7a2bccd7797d 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -12,6 +12,7 @@ #define TURRET_FLAG_SHOOT_UNSHIELDED (1<<5) // Checks if it can shoot people that aren't mindshielded and who arent heads #define TURRET_FLAG_SHOOT_BORGS (1<<6) // checks if it can shoot cyborgs #define TURRET_FLAG_SHOOT_MANAGEMENT (1<<7) // checks if it can shoot at management +#define TURRET_FLAG_SHOOT_ENGINEERS (1<<8) // checks if it can shoot at engineers DEFINE_BITFIELD(turret_flags, list( "TURRET_FLAG_SHOOT_ALL_REACT" = TURRET_FLAG_SHOOT_ALL_REACT, @@ -548,6 +549,12 @@ TYPEINFO_DEF(/obj/machinery/porta_turret) if(apparent_job?.departments_bitflags & DEPARTMENT_BITFLAG_MANAGEMENT) return 0 + // If we aren't shooting daedalus staff. + if (!(turret_flags & TURRET_FLAG_SHOOT_ENGINEERS)) + var/datum/job/apparent_job = SSjob.GetJob(perp.get_assignment()) + if(apparent_job?.departments_bitflags & DEPARTMENT_BITFLAG_ENGINEERING) + return 0 + if(turret_flags & TURRET_FLAG_AUTH_WEAPONS) //check for weapon authorization if(!istype(perp.wear_id?.GetID(), /obj/item/card/id/advanced/chameleon)) diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 5f8bb2776c2e..cfc606ebd404 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -240,12 +240,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) new /obj/structure/ai_core/latejoin_inactive(loc) return ..() -/obj/effect/landmark/start/ai/secondary - icon = 'icons/effects/landmarks_static.dmi' - icon_state = "ai_spawn" - primary_ai = FALSE - latejoin_active = FALSE - //Antagonist spawns /obj/effect/landmark/start/wizard diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index d3e0d354c9f1..2b45a3fbe0c2 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -73,3 +73,56 @@ layer = FLOAT_LAYER vis_flags = VIS_INHERIT_ID appearance_flags = KEEP_TOGETHER | LONG_GLIDE | PIXEL_SCALE + +/obj/effect/overlay/ai_holder + icon = 'goon/icons/obj/96x96.dmi' + icon_state = "oldai-01" + + var/mob/living/silicon/ai/ai + + vis_flags = VIS_INHERIT_ID | VIS_INHERIT_LAYER | VIS_INHERIT_PLANE + pixel_x = -32 + pixel_y = -32 + +/obj/effect/overlay/ai_holder/Destroy(force) + ai = null + return ..() + +/obj/effect/overlay/ai_holder/update_overlays() + . = ..() + if(ai.stat != CONSCIOUS) + return + + . += image(icon, "oldai-[ai.face_state]") + . += emissive_appearance(icon, "oldai-[ai.face_state]", alpha = 70) + + . += image(icon, "oldai-faceoverlay") + . += emissive_appearance(icon, "oldai-faceoverlay", alpha = 70) + + var/image/light = image(icon, "oldai-light") + light.plane = ABOVE_LIGHTING_PLANE + . += light + +/// Fade away the face. Kind of hacky but I don't care. +/obj/effect/overlay/ai_holder/proc/death_animation(progress = 1) + cut_overlays() + if(QDELETED(ai) || progress >= 4) // There's 4 face fade states. + return + + if(ai.stat == CONSCIOUS) + update_appearance() // Reset to the normal living state. + return + + var/list/new_overlays = list() + new_overlays += image(icon, "oldai-face_fade0[progress]") + new_overlays += emissive_appearance(icon, "oldai-face_fade0[progress]", alpha = 70) + + new_overlays += image(icon, "oldai-faceoverlay") + new_overlays += emissive_appearance(icon, "oldai-faceoverlay", alpha = 70) + + var/image/light = image(icon, "oldai-light") + light.plane = ABOVE_LIGHTING_PLANE + new_overlays += light + add_overlay(new_overlays) + + addtimer(CALLBACK(src, PROC_REF(death_animation), progress + 1), 1 SECONDS) diff --git a/code/game/objects/effects/spawners/random/techstorage.dm b/code/game/objects/effects/spawners/random/techstorage.dm index ad421c720ced..bb7921974065 100644 --- a/code/game/objects/effects/spawners/random/techstorage.dm +++ b/code/game/objects/effects/spawners/random/techstorage.dm @@ -48,7 +48,6 @@ /obj/effect/spawner/random/techstorage/rnd_all name = "RnD circuit board spawner" loot = list( - /obj/item/circuitboard/computer/aifixer, /obj/item/circuitboard/machine/fabricator/omni, /obj/item/circuitboard/machine/circuit_imprinter, /obj/item/circuitboard/computer/teleporter, diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index 7ef59e1d1760..8fd54149c3be 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -355,11 +355,6 @@ //Science -/obj/item/circuitboard/computer/aifixer - name = "AI Integrity Restorer (Computer Board)" - greyscale_colors = CIRCUIT_COLOR_SCIENCE - build_path = /obj/machinery/computer/aifixer - /obj/item/circuitboard/computer/launchpad_console name = "Launchpad Control Console (Computer Board)" greyscale_colors = CIRCUIT_COLOR_SCIENCE diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm deleted file mode 100644 index 66cb976738e2..000000000000 --- a/code/game/objects/items/devices/aicard.dm +++ /dev/null @@ -1,116 +0,0 @@ -/obj/item/aicard - name = "intelliCard" - desc = "A storage device for AIs. Patent pending." - icon = 'icons/obj/aicards.dmi' - icon_state = "aicard" // aicard-full - inhand_icon_state = "electronic" - worn_icon_state = "electronic" - lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - w_class = WEIGHT_CLASS_SMALL - slot_flags = ITEM_SLOT_BELT - item_flags = NOBLUDGEON - var/flush = FALSE - var/mob/living/silicon/ai/AI - -/obj/item/aicard/aitater - name = "intelliTater" - desc = "A stylish upgrade (?) to the intelliCard." - icon_state = "aitater" - -/obj/item/aicard/aispook - name = "intelliLantern" - desc = "A spoOoOoky upgrade to the intelliCard." - icon_state = "aispook" - -/obj/item/aicard/suicide_act(mob/living/user) - user.visible_message(span_suicide("[user] is trying to upload [user.p_them()]self into [src]! That's not going to work out well!")) - return BRUTELOSS - -/obj/item/aicard/pre_attack(atom/target, mob/living/user, params) - if(AI) //AI is on the card, implies user wants to upload it. - var/our_ai = AI - target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src) - if(!AI) - log_combat(user, our_ai, "uploaded", src, "to [target].") - update_appearance() - return TRUE - else //No AI on the card, therefore the user wants to download one. - target.transfer_ai(AI_TRANS_TO_CARD, user, null, src) - if(AI) - log_combat(user, AI, "carded", src) - update_appearance() - return TRUE - return ..() - -/obj/item/aicard/update_icon_state() - if(!AI) - name = initial(name) - icon_state = initial(icon_state) - return ..() - name = "[initial(name)] - [AI.name]" - icon_state = "[initial(icon_state)][AI.stat == DEAD ? "-404" : "-full"]" - AI.cancel_camera() - return ..() - -/obj/item/aicard/update_overlays() - . = ..() - if(!AI?.control_disabled) - return - . += "[initial(icon_state)]-on" - -/obj/item/aicard/ui_state(mob/user) - return GLOB.hands_state - -/obj/item/aicard/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "Intellicard", name) - ui.open() - -/obj/item/aicard/ui_data() - var/list/data = list() - if(AI) - data["name"] = AI.name - data["laws"] = AI.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE) - data["health"] = (AI.health + 100) / 2 - data["wireless"] = !AI.control_disabled //todo disabled->enabled - data["radio"] = AI.radio_enabled - data["isDead"] = AI.stat == DEAD - data["isBraindead"] = AI.client ? FALSE : TRUE - data["wiping"] = flush - return data - -/obj/item/aicard/ui_act(action,params) - . = ..() - if(.) - return - switch(action) - if("wipe") - if(flush) - flush = FALSE - else - var/confirm = tgui_alert(usr, "Are you sure you want to wipe this card's memory?", name, list("Yes", "No")) - if(confirm == "Yes" && !..()) - flush = TRUE - if(AI && AI.loc == src) - to_chat(AI, span_userdanger("Your core files are being wiped!")) - while(AI.stat != DEAD && flush) - AI.adjustOxyLoss(5) - AI.updatehealth() - sleep(5) - flush = FALSE - . = TRUE - if("wireless") - AI.control_disabled = !AI.control_disabled - if(!AI.control_disabled) - AI.interaction_range = null - else - AI.interaction_range = 0 - to_chat(AI, span_warning("[src]'s wireless port has been [AI.control_disabled ? "disabled" : "enabled"]!")) - . = TRUE - if("radio") - AI.radio_enabled = !AI.radio_enabled - to_chat(AI, span_warning("Your Subspace Transceiver has been [AI.radio_enabled ? "enabled" : "disabled"]!")) - . = TRUE - update_appearance() diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index ad57380e82ae..de930ff1df1b 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -1,32 +1,49 @@ /obj/structure/ai_core - density = TRUE - anchored = FALSE name = "\improper AI core" - icon = 'icons/mob/ai.dmi' - icon_state = "0" + icon = 'goon/icons/obj/96x96.dmi' + icon_state = "oldai-01" desc = "The framework for an artificial intelligence core." + + pixel_x = -32 + pixel_y = -32 + max_integrity = 500 - var/state = EMPTY_CORE + density = TRUE + anchored = TRUE + 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(mapload) . = ..() + SET_TRACKING(__TYPE__) laws = new laws.set_laws_config() + update_appearance() + +/obj/structure/ai_core/Destroy() + UNSET_TRACKING(__TYPE__) + return ..() /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_appearance() + update_appearance() if(A == brain) brain = null return ..() +/obj/structure/ai_core/update_overlays() + . = ..() + . += image(icon, "oldai-static") + . += emissive_appearance(icon, "oldai-facestatic_neutral", alpha = 70) + . += image(icon, "oldai-faceoverlay") + . += emissive_appearance(icon, "oldai-faceoverlay", alpha = 70) + + var/image/light = image(icon, "oldai-light") + light.plane = ABOVE_LIGHTING_PLANE + . += light /obj/structure/ai_core/Destroy() QDEL_NULL(circuit) @@ -38,7 +55,6 @@ name = "inactive AI" icon_state = "ai-empty" anchored = TRUE - state = AI_READY_CORE /obj/structure/ai_core/deactivated/Initialize(mapload) . = ..() @@ -47,13 +63,10 @@ /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" + icon_state = "oldai-01" anchored = TRUE - state = AI_READY_CORE + var/available = TRUE - var/safety_checks = TRUE - var/active = TRUE /obj/structure/ai_core/latejoin_inactive/Initialize(mapload) . = ..() @@ -64,20 +77,13 @@ GLOB.latejoin_ai_cores -= src return ..() -/obj/structure/ai_core/latejoin_inactive/examine(mob/user) - . = ..() - . += "Its transmitter seems to be [active? "on" : "off"]." - . += span_notice("You could [active? "deactivate" : "activate"] it with a multitool.") - /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) @@ -88,214 +94,9 @@ 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_notice("You [active? "activate" : "deactivate"] \the [src]'s transmitters.")) - return - return ..() - -/obj/structure/ai_core/wrench_act(mob/living/user, obj/item/tool) - . = ..() - default_unfasten_wrench(user, tool) - return ITEM_INTERACT_SUCCESS - -/obj/structure/ai_core/attackby(obj/item/P, mob/user, params) - if(!anchored) - if(P.tool_behaviour == TOOL_WELDER && can_deconstruct) - if(state != EMPTY_CORE) - to_chat(user, span_warning("The core must be empty to deconstruct it!")) - return - - if(!P.tool_start_check(user, amount=0)) - return - - to_chat(user, span_notice("You start to deconstruct the frame...")) - if(P.use_tool(src, user, 20, volume=50) && state == EMPTY_CORE) - to_chat(user, span_notice("You deconstruct the frame.")) - 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_notice("You place the circuit board inside the frame.")) - update_appearance() - state = CIRCUIT_CORE - circuit = P - return - if(CIRCUIT_CORE) - if(P.tool_behaviour == TOOL_SCREWDRIVER) - P.play_tool_sound(src) - to_chat(user, span_notice("You screw the circuit board into place.")) - state = SCREWED_CORE - update_appearance() - return - if(P.tool_behaviour == TOOL_CROWBAR) - P.play_tool_sound(src) - to_chat(user, span_notice("You remove the circuit board.")) - state = EMPTY_CORE - update_appearance() - 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_notice("You unfasten the circuit board.")) - state = CIRCUIT_CORE - update_appearance() - 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_notice("You start to add cables to the frame...")) - if(do_after(user, src, 2 SECONDS) && state == SCREWED_CORE && C.use(5)) - to_chat(user, span_notice("You add cables to the frame.")) - state = CABLED_CORE - update_appearance() - else - to_chat(user, span_warning("You need five lengths of cable to wire the AI core!")) - return - if(CABLED_CORE) - if(P.tool_behaviour == TOOL_WIRECUTTER) - if(brain) - to_chat(user, span_warning("Get that [brain.name] out of there first!")) - else - P.play_tool_sound(src) - to_chat(user, span_notice("You remove the cables.")) - state = SCREWED_CORE - update_appearance() - 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_notice("You start to put in the glass panel...")) - if(do_after(user, src, 2 SECONDS) && state == CABLED_CORE && G.use(2)) - to_chat(user, span_notice("You put in the glass panel.")) - state = GLASS_CORE - update_appearance() - else - to_chat(user, span_warning("You need two sheets of reinforced glass to insert them into the AI core!")) - return - - if(istype(P, /obj/item/ai_module)) - if(brain && brain.laws.id != DEFAULT_AI_LAWID) - to_chat(user, span_warning("The installed [brain.name] already has set laws!")) - 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, JOB_AI) && !QDELETED(src) && !QDELETED(user) && !QDELETED(M) && !QDELETED(user) && Adjacent(user))) - if(!QDELETED(M)) - to_chat(user, span_warning("This [M.name] does not seem to fit!")) - return - if(!user.transferItemToLoc(M,src)) - return - - brain = M - to_chat(user, span_notice("You add [M.name] to the frame.")) - update_appearance() - return - - if(P.tool_behaviour == TOOL_CROWBAR && brain) - P.play_tool_sound(src) - to_chat(user, span_notice("You remove the brain.")) - brain.forceMove(loc) - brain = null - update_appearance() - return - - if(GLASS_CORE) - if(P.tool_behaviour == TOOL_CROWBAR) - P.play_tool_sound(src) - to_chat(user, span_notice("You remove the glass panel.")) - state = CABLED_CORE - update_appearance() - new /obj/item/stack/sheet/rglass(loc, 2) - return - - if(P.tool_behaviour == TOOL_SCREWDRIVER) - P.play_tool_sound(src) - to_chat(user, span_notice("You connect the monitor.")) - if(brain) - var/mob/living/brain/B = brain.brainmob - B.mind?.remove_antags_for_borging() - - 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 [get_area_name(A, TRUE)].", span_name("[A]"), follow_target=A, message_type=DEADCHAT_ANNOUNCEMENT) - qdel(src) - else - state = AI_READY_CORE - update_appearance() - 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_notice("You disconnect the monitor.")) - state = GLASS_CORE - update_appearance() - 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" - return ..() - -/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) +/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 /* This is a good place for AI-related object verbs so I'm sticking it here. @@ -305,29 +106,18 @@ 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_alert("ERROR: AI flush is in progress, cannot execute transfer protocol.")) - return FALSE +/atom/proc/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI) 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_notice("You have been uploaded to a stationary terminal. Remote device connection restored.")) - to_chat(user, "[span_boldnotice("Transfer successful")]: [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_alert("There is no AI loaded on this terminal.")) +/obj/structure/ai_core/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI) + . = ..() + if(!.) + return FALSE -/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 + AI.control_disabled = FALSE + AI.radio_enabled = TRUE + AI.forceMove(loc) // to replace the terminal. + to_chat(AI, span_notice("You have been uploaded to a stationary terminal. Remote device connection restored.")) + to_chat(user, "[span_boldnotice("Transfer successful")]: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") + AI.battery = circuit.battery + qdel(src) diff --git a/code/game/objects/structures/ai_fluff.dm b/code/game/objects/structures/ai_fluff.dm new file mode 100644 index 000000000000..5b99d50c18e1 --- /dev/null +++ b/code/game/objects/structures/ai_fluff.dm @@ -0,0 +1,17 @@ +#warn name desc +/obj/structure/ai_fluff + icon = 'goon/icons/obj/96x96.dmi' + icon_state = "oldai-t2" + + layer = HIGH_OBJ_LAYER + + resistance_flags = INDESTRUCTIBLE + density = TRUE + anchored = TRUE + + pixel_x = -32 + pixel_y = -32 + +/obj/structure/ai_fluff/brad + icon = 'goon/icons/obj/96x96.dmi' + icon_state = "oldai-t1" diff --git a/code/modules/admin/verbs/ai_triumvirate.dm b/code/modules/admin/verbs/ai_triumvirate.dm deleted file mode 100644 index ca7ebfe7cc43..000000000000 --- a/code/modules/admin/verbs/ai_triumvirate.dm +++ /dev/null @@ -1,48 +0,0 @@ - -///global reference to the current theme, if there is one. -GLOBAL_DATUM(triple_ai_controller, /datum/triple_ai_controller) - -/** - * The triple ai controller handles the admin triple AI mode, if enabled. - * It is first created when "Toggle AI Triumvirate" triggers it, and it can be referenced from GLOB.triple_ai_controller - * After it handles roundstart business, it cleans itself up. - */ -/datum/triple_ai_controller - -/datum/triple_ai_controller/New() - . = ..() - RegisterSignal(SSjob, COMSIG_OCCUPATIONS_DIVIDED, PROC_REF(on_occupations_divided)) - -/datum/triple_ai_controller/proc/on_occupations_divided(datum/source) - SIGNAL_HANDLER - - for(var/datum/job/ai/ai_datum in SSjob.joinable_occupations) - ai_datum.spawn_positions = 3 - for(var/obj/effect/landmark/start/ai/secondary/secondary_ai_spawn in GLOB.start_landmarks_list) - secondary_ai_spawn.latejoin_active = TRUE - qdel(src) - -/datum/triple_ai_controller/Destroy(force) - UnregisterSignal(SSjob, COMSIG_OCCUPATIONS_DIVIDED) - GLOB.triple_ai_controller = null - . = ..() - -/client/proc/triple_ai() - set category = "Admin.Events" - set name = "Toggle AI Triumvirate" - - if(SSticker.current_state > GAME_STATE_PREGAME) - to_chat(usr, "This option is currently only usable during pregame. This may change at a later date.", confidential = TRUE) - return - - var/datum/job/job = SSjob.GetJobType(/datum/job/ai) - if(!job) - to_chat(usr, "Unable to locate the AI job", confidential = TRUE) - CRASH("triple_ai() called, no /datum/job/ai to be found.") - - if(!GLOB.triple_ai_controller) - GLOB.triple_ai_controller = new() - else - QDEL_NULL(GLOB.triple_ai_controller) - to_chat(usr, "There will[GLOB.triple_ai_controller ? "" : "not"] be an AI Triumvirate at round start.") - message_admins(span_adminnotice("[key_name_admin(usr)] has toggled [GLOB.triple_ai_controller ? "on" : "off"] triple AIs at round start.")) diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index f8e5e79526ed..974c34caca0d 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -255,11 +255,6 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller) return holder.anon_names() SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Anonymous Names")) - if("tripleAI") - if(!is_funmin) - return - holder.triple_ai() - SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Triple AI")) if("onlyone") if(!is_funmin) return diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index bb6c03bc78d4..906359064814 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -531,7 +531,7 @@ GLOBAL_LIST_INIT(job_display_order, list( fully_replace_character_name(real_name, GLOB.current_anonymous_theme.anonymous_ai_name(TRUE)) return apply_pref_name(/datum/preference/name/ai, player_client) // This proc already checks if the player is appearance banned. - set_core_display_icon(null, player_client) + // set_core_display_icon(null, player_client) /mob/living/silicon/robot/apply_prefs_job(client/player_client, datum/job/job) diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm index 76711faaba4f..3b3f13e87605 100644 --- a/code/modules/jobs/job_types/ai.dm +++ b/code/modules/jobs/job_types/ai.dm @@ -2,7 +2,6 @@ title = JOB_AI description = "Assist the crew, follow your laws, coordinate your cyborgs." radio_help_message = "Prefix your message with :b to speak with cyborgs and other AIs." - auto_deadmin_role_flags = DEADMIN_POSITION_SILICON faction = FACTION_STATION total_positions = 1 @@ -35,9 +34,12 @@ for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs) if(!R.connected_ai) R.TryConnectToAI() + var/mob/living/silicon/ai/ai_spawn = spawned ai_spawn.log_current_laws() + // There's no real reason for this to actually be in datacore on ready, its just an arbitrary delay and it's in sync with AAS messages. + SSdatacore.OnReady(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(priority_announce), "Integrated Intelligence Unit designated \"[ai_spawn.real_name]\" boot sequence successful.", )) /datum/job/ai/get_roundstart_spawn_point_fixed() return get_latejoin_spawn_point() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 6d50df3cff91..e3649d8dda78 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -29,7 +29,7 @@ GLOBAL_VAR_INIT(fresh_ghost_adjectives, __fresh_ghost_adjectives()) shift_to_open_context_menu = FALSE simulated = FALSE - var/can_reenter_corpse + var/can_reenter_corpse = TRUE var/datum/hud/living/carbon/hud = null // hud var/bootime = 0 @@ -65,7 +65,7 @@ GLOBAL_VAR_INIT(fresh_ghost_adjectives, __fresh_ghost_adjectives()) var/datum/spawners_menu/spawners_menu var/datum/minigames_menu/minigames_menu -/mob/dead/observer/Initialize(mapload, started_as_observer = FALSE, admin_ghost = FALSE) +/mob/dead/observer/Initialize(mapload, started_as_observer = FALSE, admin_ghost = FALSE, can_reenter_corpse = TRUE) src.started_as_observer = started_as_observer src.admin_ghost = admin_ghost @@ -297,7 +297,7 @@ Works together with spawning an observer, noted above. ethereal_heart.stop_crystalization_process(crystal_fella) //stops the crystallization process stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now - var/mob/dead/observer/ghost = new(src, FALSE, admin_ghost) // Transfer safety to observer spawning proc. + var/mob/dead/observer/ghost = new(src, FALSE, admin_ghost, can_reenter_corpse) // Transfer safety to observer spawning proc. SStgui.on_transfer(src, ghost) // Transfer NanoUIs. ghost.verb_say = verb_say @@ -786,13 +786,29 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp gas_scan = TRUE /mob/dead/observer/proc/set_ghost_appearance(mob/living/to_copy) - var/mutable_appearance/appearance = to_copy?.mind?.body_appearance || to_copy + cut_viscontents() + overlays.Cut() + if(isAI(to_copy)) // Yay I love hacks + icon = null + icon_state = null + alpha = 127 + var/obj/effect/overlay/holder = new + holder.vis_flags = VIS_INHERIT_ID | VIS_INHERIT_LAYER | VIS_INHERIT_PLANE + holder.icon = /obj/effect/overlay/ai_holder::icon + holder.icon_state = /obj/effect/overlay/ai_holder::icon_state + holder.pixel_x = -32 + holder.pixel_y = -32 + holder.overlays += image(/obj/effect/overlay/ai_holder::icon, "oldai-static") + holder.overlays += image(/obj/effect/overlay/ai_holder::icon, "oldai-faceoverlay") + add_viscontents(holder) + return + + var/mutable_appearance/appearance = to_copy?.mind?.body_appearance || to_copy if(!appearance || !appearance.icon) icon = initial(icon) icon_state = "ghost" alpha = 255 - overlays.Cut() else icon = appearance.icon icon_state = appearance.icon_state diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index fd73bf2f0cd3..a0d06286d9e5 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -230,11 +230,11 @@ src.stamina.adjust(-stamina) if(jitter && (status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) - adjust_timed_status_effect(jitter, /datum/status_effect/jitter) + adjust_timed_status_effect(jitter, /datum/status_effect/jitter, jitter) if(slur) - adjust_timed_status_effect(slur, /datum/status_effect/speech/slurring/drunk) + adjust_timed_status_effect(slur, /datum/status_effect/speech/slurring/drunk, slur) if(stutter) - adjust_timed_status_effect(stutter, /datum/status_effect/speech/stutter) + adjust_timed_status_effect(stutter, /datum/status_effect/speech/stutter, stutter) return TRUE diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index ca009067caf2..994cd1452f2f 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -106,7 +106,7 @@ key_third_person = "deathgasps" message = "seizes up and falls limp, their eyes dead and lifeless..." message_robot = "gives one shrill beep before falling lifeless." - message_AI = "screeches, its screen flickering as its systems slowly halt." + message_AI = "emits a loud beep as its hum fades away." message_alien = "lets out a waning guttural screech, and collapses onto the floor..." message_larva = "lets out a sickly hiss of air and falls limply to the floor..." message_monkey = "lets out a faint chimper as it collapses and stops moving..." diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 9ffce3f80367..d908f21c98d8 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -11,25 +11,31 @@ subject.attack_ai(M) return is_in_use - +#warn desc /mob/living/silicon/ai name = "AI" real_name = "AI" icon = 'icons/mob/ai.dmi' - icon_state = "ai" + icon_state = "" + move_resist = MOVE_FORCE_OVERPOWERING density = TRUE - status_flags = CANSTUN|CANPUSH + + status_flags = CANSTUN combat_mode = TRUE //so we always get pushed instead of trying to swap sight = SEE_TURFS | SEE_MOBS | SEE_OBJS + see_in_dark = NIGHTVISION_FOV_RANGE hud_type = /datum/hud/ai + med_hud = DATA_HUD_MEDICAL_BASIC sec_hud = DATA_HUD_SECURITY_BASIC d_hud = DATA_HUD_DIAGNOSTIC_ADVANCED - mob_size = MOB_SIZE_LARGE + mob_size = MOB_SIZE_HUGE + radio = /obj/item/radio/headset/silicon/ai can_buckle_to = FALSE + var/battery = 200 //emergency power if the AI's APC is off var/list/network = list("ss13") var/obj/machinery/camera/current @@ -115,6 +121,11 @@ COOLDOWN_DECLARE(command_report_cd) /// An image to add to client.images so the AI player can see their own eye sprite. var/image/sense_of_self + /// The vis contents holder for our overlays, for offsetting without breaking things like runechat. + var/obj/effect/overlay/ai_holder/vis_holder + + /// The icon state for the face. + var/face_state = "static" /mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai) . = ..() @@ -156,7 +167,11 @@ if(client) INVOKE_ASYNC(src, PROC_REF(apply_pref_name), /datum/preference/name/ai, client) - INVOKE_ASYNC(src, PROC_REF(set_core_display_icon)) + vis_holder = new + vis_holder.ai = src + add_viscontents(vis_holder) + + //INVOKE_ASYNC(src, PROC_REF(set_core_display_icon)) holo_icon = getHologramIcon(icon('icons/mob/ai.dmi',"default")) @@ -197,6 +212,8 @@ RegisterSignal(alert_control.listener, COMSIG_ALARM_TRIGGERED, PROC_REF(alarm_triggered)) RegisterSignal(alert_control.listener, COMSIG_ALARM_CLEARED, PROC_REF(alarm_cleared)) + update_appearance() + /mob/living/silicon/ai/key_down(_key, client/user) if(findtext(_key, "numpad")) //if it's a numpad number, we can convert it to just the number _key = _key[7] //strings, lists, same thing really @@ -230,6 +247,7 @@ QDEL_NULL(robot_control) QDEL_NULL(aiMulti) QDEL_NULL(alert_control) + QDEL_NULL(vis_holder) malfhack = null current = null bot_ref = null @@ -278,6 +296,10 @@ /mob/living/silicon/ai/broadcast_examine(atom/examined) return +/mob/living/silicon/ai/update_appearance(updates) + . = ..() + vis_holder.update_appearance(updates) + /// Returns the nearest lit camera to a mob, as long as the camera can see that mob. /mob/living/silicon/ai/proc/get_nearest_lit_camera_to_mob(mob/M) var/smallest_dist = INFINITY @@ -296,41 +318,37 @@ /mob/living/silicon/ai/ignite_mob() return FALSE -/mob/living/silicon/ai/proc/set_core_display_icon(input, client/C) - if(client && !C) - C = client - if(!input && !C?.prefs?.read_preference(/datum/preference/choiced/ai_core_display)) - icon_state = initial(icon_state) - else - var/preferred_icon = input ? input : C.prefs.read_preference(/datum/preference/choiced/ai_core_display) - icon_state = resolve_ai_icon(preferred_icon) - -/mob/living/silicon/ai/verb/pick_icon() - set category = "AI Commands" - set name = "Set AI Core Display" - if(incapacitated()) - return - icon = initial(icon) - icon_state = "ai" - cut_overlays() - var/list/iconstates = GLOB.ai_core_display_screens - for(var/option in iconstates) - if(option == "Random") - iconstates[option] = image(icon = src.icon, icon_state = "ai-random") - continue - if(option == "Portrait") - iconstates[option] = image(icon = src.icon, icon_state = "ai-portrait") - continue - iconstates[option] = image(icon = src.icon, icon_state = resolve_ai_icon(option)) - - view_core() - var/ai_core_icon = show_radial_menu(src, src , iconstates, radius = 42) - - if(!ai_core_icon || incapacitated()) - return - - display_icon_override = ai_core_icon - set_core_display_icon(ai_core_icon) +/// Sets the face_state and updates it. +/mob/living/silicon/ai/proc/set_face_state(new_state) + face_state = new_state + update_appearance(UPDATE_OVERLAYS) + +// /mob/living/silicon/ai/verb/pick_icon() +// set category = "AI Commands" +// set name = "Set AI Core Display" +// if(incapacitated()) +// return +// icon = initial(icon) +// icon_state = "ai" +// cut_overlays() +// var/list/iconstates = GLOB.ai_core_display_screens +// for(var/option in iconstates) +// if(option == "Random") +// iconstates[option] = image(icon = src.icon, icon_state = "ai-random") +// continue +// if(option == "Portrait") +// iconstates[option] = image(icon = src.icon, icon_state = "ai-portrait") +// continue +// iconstates[option] = image(icon = src.icon, icon_state = resolve_ai_icon(option)) + +// view_core() +// var/ai_core_icon = show_radial_menu(src, src , iconstates, radius = 42) + +// if(!ai_core_icon || incapacitated()) +// return + +// display_icon_override = ai_core_icon +// set_core_display_icon(ai_core_icon) /mob/living/silicon/ai/get_status_tab_items() . = ..() @@ -819,29 +837,6 @@ return set_autosay() -/mob/living/silicon/ai/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) - if(!..()) - return - if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card. - if(!can_be_carded) - to_chat(user, span_boldwarning("Transfer failed.")) - return - disconnect_shell() //If the AI is controlling a borg, force the player back to core! - if(!mind) - to_chat(user, span_warning("No intelligence patterns detected.")) - return - ShutOffDoomsdayDevice() - var/obj/structure/ai_core/new_core = new /obj/structure/ai_core/deactivated(loc)//Spawns a deactivated terminal at AI location. - new_core.circuit.battery = battery - ai_restore_power()//So the AI initially has power. - control_disabled = TRUE //Can't control things remotely if you're stuck in a card! - interaction_range = 0 - radio_enabled = FALSE //No talking on the built-in radio for you either! - forceMove(card) - card.AI = src - to_chat(src, "You have been downloaded to a mobile storage device. Remote device connection severed.") - to_chat(user, "[span_boldnotice("Transfer successful")]: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.") - /mob/living/silicon/ai/canUseTopic(atom/movable/target, flags) if(control_disabled) to_chat(src, span_warning("You can't do that right now!")) @@ -962,7 +957,7 @@ /mob/living/silicon/ai/revive(full_heal = FALSE, admin_revive = FALSE) . = ..() if(.) //successfully ressuscitated from death - set_core_display_icon(display_icon_override) + //set_core_display_icon(display_icon_override) set_eyeobj_visible(TRUE) /mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc) diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index 172ab7faa158..babc3caa9aba 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -9,21 +9,12 @@ . = ..() SSblackbox.record_feedback("amount", "ai_deaths", 1) - cut_overlays() //remove portraits - var/old_icon = icon_state - if("[icon_state]_dead" in icon_states(icon)) - icon_state = "[icon_state]_dead" - else - icon_state = "ai_dead" - if("[old_icon]_death_transition" in icon_states(icon)) - z_flick("[old_icon]_death_transition", src) - cameraFollow = null + update_appearance() + if(!gibbed && !QDELING(src)) + vis_holder.death_animation() - set_anchored(FALSE) //unbolt floorbolts - status_flags |= CANPUSH //we want it to be pushable when unanchored on death - REMOVE_TRAIT(src, TRAIT_NO_TELEPORT, AI_ANCHOR_TRAIT) //removes the anchor trait, because its not anchored anymore - move_resist = MOVE_FORCE_NORMAL + cameraFollow = null if(eyeobj) eyeobj.setLoc(get_turf(src)) @@ -38,13 +29,6 @@ if(explosive) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(explosion), loc, 3, 6, 12, null, 15), 1 SECONDS) - if(istype(loc, /obj/item/aicard/aitater)) - loc.icon_state = "aitater-404" - else if(istype(loc, /obj/item/aicard/aispook)) - loc.icon_state = "aispook-404" - else if(istype(loc, /obj/item/aicard)) - loc.icon_state = "aicard-404" - /mob/living/silicon/ai/proc/ShutOffDoomsdayDevice() if(nuking) nuking = FALSE diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 8b4e91a5f7aa..bfe6fc4ac0ac 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -201,8 +201,10 @@ /mob/living/silicon/ai/proc/set_eyeobj_visible(state = TRUE) if(!eyeobj) return + eyeobj.mouse_opacity = state ? MOUSE_OPACITY_ICON : initial(eyeobj.mouse_opacity) eyeobj.invisibility = state ? INVISIBILITY_OBSERVER : initial(eyeobj.invisibility) + sense_of_self?.invisibility = state ? INVISIBILITY_OBSERVER : INVISIBLITY_VISIBLE /mob/living/silicon/ai/verb/toggle_acceleration() set category = "AI Commands" diff --git a/code/modules/mob/living/silicon/ai/login.dm b/code/modules/mob/living/silicon/ai/login.dm index f36dc84c08bf..f8a9be4ba1d3 100644 --- a/code/modules/mob/living/silicon/ai/login.dm +++ b/code/modules/mob/living/silicon/ai/login.dm @@ -2,10 +2,15 @@ . = ..() if(!. || !client) return FALSE + if(stat != DEAD) if(lacks_power() && apc_override) //Placing this in Login() in case the AI doesn't have this link for whatever reason. to_chat(usr, "[span_warning("Main power is unavailable, backup power in use. Diagnostics scan complete.")] Local APC ready for connection.") + set_eyeobj_visible(TRUE) + if(multicam_on) end_multicam() + view_core() + set_face_state("face_neutral") diff --git a/code/modules/mob/living/silicon/ai/logout.dm b/code/modules/mob/living/silicon/ai/logout.dm index a027871716ef..c0c8f30d2c97 100644 --- a/code/modules/mob/living/silicon/ai/logout.dm +++ b/code/modules/mob/living/silicon/ai/logout.dm @@ -2,3 +2,4 @@ ..() set_eyeobj_visible(FALSE) view_core() + set_face_state("static") diff --git a/code/modules/mod/mod_ai.dm b/code/modules/mod/mod_ai.dm index a5fd904093a3..ab5a006357a1 100644 --- a/code/modules/mod/mod_ai.dm +++ b/code/modules/mod/mod_ai.dm @@ -1,59 +1,3 @@ -/obj/item/mod/control/transfer_ai(interaction, mob/user, mob/living/silicon/ai/intAI, obj/item/aicard/card) - . = ..() - if(!.) - return - if(!open) //mod must be open - balloon_alert(user, "suit must be open to transfer!") - return - switch(interaction) - if(AI_TRANS_TO_CARD) - if(!ai) - balloon_alert(user, "no AI in suit!") - return - balloon_alert(user, "transferring to card...") - if(!do_after(user, src, 5 SECONDS)) - balloon_alert(user, "interrupted!") - return - if(!ai) - return - intAI = ai - intAI.ai_restore_power()//So the AI initially has power. - intAI.control_disabled = TRUE - intAI.radio_enabled = FALSE - intAI.disconnect_shell() - intAI.forceMove(card) - card.AI = intAI - for(var/datum/action/action as anything in actions) - action.Remove(intAI) - intAI.controlled_equipment = null - intAI.remote_control = null - balloon_alert(intAI, "transferred to a card") - balloon_alert(user, "AI transferred to card") - ai = null - - if(AI_TRANS_FROM_CARD) //Using an AI card to upload to the suit. - intAI = card.AI - if(!intAI) - balloon_alert(user, "no AI in card!") - return - if(ai) - balloon_alert(user, "already has AI!") - return - if(intAI.deployed_shell) //Recall AI if shelled so it can be checked for a client - intAI.disconnect_shell() - if(intAI.stat || !intAI.client) - balloon_alert(user, "AI unresponsive!") - return - balloon_alert(user, "transferring to suit...") - if(!do_after(user, src, 5 SECONDS)) - balloon_alert(user, "interrupted!") - return - if(ai) - return - balloon_alert(user, "AI transferred to suit") - ai_enter_mod(intAI) - card.AI = null - /obj/item/mod/control/proc/ai_enter_mod(mob/living/silicon/ai/new_ai) new_ai.control_disabled = FALSE new_ai.radio_enabled = TRUE @@ -101,49 +45,3 @@ if(!wearer) return REMOVE_TRAIT(wearer, TRAIT_FORCED_STANDING, MOD_TRAIT) - -/obj/item/mod/ai_minicard - name = "AI mini-card" - desc = "A small card designed to eject dead AIs. You could use an intellicard to recover it." - icon = 'icons/obj/aicards.dmi' - icon_state = "minicard" - var/datum/weakref/stored_ai - -/obj/item/mod/ai_minicard/Initialize(mapload, mob/living/silicon/ai/ai) - . = ..() - if(!ai) - return - ai.apply_damage(150, BURN) - INVOKE_ASYNC(ai, TYPE_PROC_REF(/mob/living/silicon/ai, death)) - ai.forceMove(src) - stored_ai = WEAKREF(ai) - icon_state = "minicard-filled" - -/obj/item/mod/ai_minicard/Destroy() - QDEL_NULL(stored_ai) - return ..() - -/obj/item/mod/ai_minicard/examine(mob/user) - . = ..() - . += span_notice("You see [stored_ai.resolve() || "no AI"] stored inside.") - -/obj/item/mod/ai_minicard/transfer_ai(interaction, mob/user, mob/living/silicon/ai/intAI, obj/item/aicard/card) - . = ..() - if(!.) - return - if(interaction != AI_TRANS_TO_CARD) - return - var/mob/living/silicon/ai/ai = stored_ai.resolve() - if(!ai) - balloon_alert(user, "no AI!") - return - balloon_alert(user, "transferring to card...") - if(!do_after(user, src, 5 SECONDS) || !ai) - balloon_alert(user, "interrupted!") - return - icon_state = "minicard" - ai.forceMove(card) - card.AI = ai - ai.notify_ghost_revival("You have been recovered from the wreckage!", source = card) - balloon_alert(user, "AI transferred to card") - stored_ai = null diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index 24c2666d9d38..bee5d51c2310 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -150,7 +150,17 @@ TYPEINFO_DEF(/obj/item/mod/control) for(var/datum/action/action as anything in actions) if(action.owner == ai) action.Remove(ai) - new /obj/item/mod/ai_minicard(drop_location(), ai) + + var/found_core = FALSE + for(var/obj/structure/ai_core/core as anything in INSTANCES_OF(/obj/structure/ai_core)) + if(core.transfer_ai(ai)) + found_core = TRUE + break + + if(!found_core) + qdel(ai) + ai = null + return ..() /obj/item/mod/control/examine(mob/user) diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm index baefc003545c..2d0628e16618 100644 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -49,7 +49,6 @@ var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor()) hard_drive.store_file(new/datum/computer_file/program/chatclient()) - hard_drive.store_file(new/datum/computer_file/program/aidiag()) hard_drive.store_file(new/datum/computer_file/program/robocontrol()) // ===== COMPANY CONSOLE ===== diff --git a/code/modules/modular_computers/file_system/programs/airestorer.dm b/code/modules/modular_computers/file_system/programs/airestorer.dm deleted file mode 100644 index fdf0ccd2f7f9..000000000000 --- a/code/modules/modular_computers/file_system/programs/airestorer.dm +++ /dev/null @@ -1,127 +0,0 @@ -/datum/computer_file/program/aidiag - filename = "aidiag" - filedesc = "NT FRK" - category = PROGRAM_CATEGORY_SCI - program_icon_state = "generic" - extended_desc = "Firmware Restoration Kit, capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot." - size = 12 - requires_ntnet = FALSE - usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP - transfer_access = list(ACCESS_MANAGEMENT) - available_on_ntnet = TRUE - tgui_id = "NtosAiRestorer" - program_icon = "laptop-code" - /// Variable dictating if we are in the process of restoring the AI in the inserted intellicard - var/restoring = FALSE - -/datum/computer_file/program/aidiag/proc/get_ai(cardcheck) - - var/obj/item/computer_hardware/ai_slot/ai_slot - - if(computer) - ai_slot = computer.all_components[MC_AI] - - if(computer && ai_slot?.check_functionality()) - if(cardcheck == 1) - return ai_slot - if(ai_slot.is_enabled() && ai_slot.stored_card) - if(cardcheck == 2) - return ai_slot.stored_card - if(ai_slot.stored_card.AI) - return ai_slot.stored_card.AI - - return - -/datum/computer_file/program/aidiag/ui_act(action, params) - . = ..() - if(.) - return - - var/mob/living/silicon/ai/A = get_ai() - if(!A) - restoring = FALSE - - switch(action) - if("PRG_beginReconstruction") - if(A && A.health < 100) - restoring = TRUE - A.notify_ghost_revival("Your core files are being restored!", source = computer) - return TRUE - if("PRG_eject") - if(computer.all_components[MC_AI]) - var/obj/item/computer_hardware/ai_slot/ai_slot = computer.all_components[MC_AI] - if(ai_slot?.stored_card) - ai_slot.try_eject(usr) - return TRUE - -/datum/computer_file/program/aidiag/process_tick() - . = ..() - if(!restoring) //Put the check here so we don't check for an ai all the time - return - var/obj/item/aicard/cardhold = get_ai(2) - - var/obj/item/computer_hardware/ai_slot/ai_slot = get_ai(1) - - - var/mob/living/silicon/ai/A = get_ai() - if(!A || !cardhold) - restoring = FALSE // If the AI was removed, stop the restoration sequence. - if(ai_slot) - ai_slot.locked = FALSE - return - - if(cardhold.flush) - ai_slot.locked = FALSE - restoring = FALSE - return - ai_slot.locked = TRUE - A.adjustOxyLoss(-5, FALSE) - A.adjustFireLoss(-5, FALSE) - A.adjustBruteLoss(-5, FALSE) - - // Please don't forget to update health, otherwise the below if statements will probably always fail. - A.updatehealth() - - if(A.health >= 0 && A.stat == DEAD) - A.revive(full_heal = FALSE, admin_revive = FALSE) - cardhold.update_appearance() - - // Finished restoring - if(A.health >= 100) - ai_slot.locked = FALSE - restoring = FALSE - - return TRUE - - -/datum/computer_file/program/aidiag/ui_data(mob/user) - var/list/data = get_header_data() - var/mob/living/silicon/ai/AI = get_ai() - - var/obj/item/aicard/aicard = get_ai(2) - - data["ejectable"] = TRUE - data["AI_present"] = FALSE - data["error"] = null - if(!aicard) - data["error"] = "Please insert an intelliCard." - else - if(!AI) - data["error"] = "No AI located" - else - var/obj/item/aicard/cardhold = AI.loc - if(cardhold.flush) - data["error"] = "Flush in progress" - else - data["AI_present"] = TRUE - data["name"] = AI.name - data["restoring"] = restoring - data["health"] = (AI.health + 100) / 2 - data["isDead"] = AI.stat == DEAD - data["laws"] = AI.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE) - - return data - -/datum/computer_file/program/aidiag/kill_program(forced) - restoring = FALSE - return ..() diff --git a/code/modules/power/apc/apc_malf.dm b/code/modules/power/apc/apc_malf.dm index 02bff5905808..7ddbc4ad1b70 100644 --- a/code/modules/power/apc/apc_malf.dm +++ b/code/modules/power/apc/apc_malf.dm @@ -76,56 +76,3 @@ disk_pinpointers.switch_mode_to(TRACK_NUKE_DISK) disk_pinpointers.alert = FALSE -/obj/machinery/power/apc/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) - if(card.AI) - to_chat(user, span_warning("[card] is already occupied!")) - return - if(!occupier) - to_chat(user, span_warning("There's nothing in [src] to transfer!")) - return - if(!occupier.mind || !occupier.client) - to_chat(user, span_warning("[occupier] is either inactive or destroyed!")) - return - if(!occupier.parent.stat) - to_chat(user, span_warning("[occupier] is refusing all attempts at transfer!") ) - return - if(transfer_in_progress) - to_chat(user, span_warning("There's already a transfer in progress!")) - return - if(interaction != AI_TRANS_TO_CARD || occupier.stat) - return - var/turf/user_turf = get_turf(user) - if(!user_turf) - return - transfer_in_progress = TRUE - user.visible_message(span_notice("[user] slots [card] into [src]..."), span_notice("Transfer process initiated. Sending request for AI approval...")) - playsound(src, 'sound/machines/click.ogg', 50, TRUE) - SEND_SOUND(occupier, sound('sound/misc/notice2.ogg')) //To alert the AI that someone's trying to card them if they're tabbed out - if(tgui_alert(occupier, "[user] is attempting to transfer you to \a [card.name]. Do you consent to this?", "APC Transfer", list("Yes - Transfer Me", "No - Keep Me Here")) == "No - Keep Me Here") - to_chat(user, span_danger("AI denied transfer request. Process terminated.")) - playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE) - transfer_in_progress = FALSE - return - if(user.loc != user_turf) - to_chat(user, span_danger("Location changed. Process terminated.")) - to_chat(occupier, span_warning("[user] moved away! Transfer canceled.")) - transfer_in_progress = FALSE - return - to_chat(user, span_notice("AI accepted request. Transferring stored intelligence to [card]...")) - to_chat(occupier, span_notice("Transfer starting. You will be moved to [card] shortly.")) - if(!do_after(user, src, 50)) - to_chat(occupier, span_warning("[user] was interrupted! Transfer canceled.")) - transfer_in_progress = FALSE - return - if(!occupier || !card) - transfer_in_progress = FALSE - return - user.visible_message(span_notice("[user] transfers [occupier] to [card]!"), span_notice("Transfer complete! [occupier] is now stored in [card].")) - to_chat(occupier, span_notice("Transfer complete! You've been stored in [user]'s [card.name].")) - occupier.forceMove(card) - card.AI = occupier - occupier.parent.shunted = FALSE - occupier.cancel_camera() - occupier = null - transfer_in_progress = FALSE - return diff --git a/code/modules/research/designs/comp_board_designs.dm b/code/modules/research/designs/comp_board_designs.dm index 3e2e12c02099..9fa8906d6d25 100644 --- a/code/modules/research/designs/comp_board_designs.dm +++ b/code/modules/research/designs/comp_board_designs.dm @@ -176,12 +176,6 @@ id = "message_monitor" build_path = /obj/item/circuitboard/computer/message_monitor -/datum/design/board/aifixer - name = "Circuit Board (AI Integrity Restorer)" - desc = "Allows for the construction of circuit boards used to build an AI Integrity Restorer." - id = "aifixer" - build_path = /obj/item/circuitboard/computer/aifixer - /datum/design/board/libraryconsole name = "Circuit Board (Library Console)" desc = "Allows for the construction of circuit boards used to build a new library console." diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 435807d67d88..59553c5b4b72 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -900,39 +900,6 @@ TYPEINFO_DEF(/obj/vehicle/sealed/mecha) //Transfer from core or card to mech. Proc is called by mech. switch(interaction) - if(AI_TRANS_TO_CARD) //Upload AI from mech to AI card. - if(!construction_state) //Mech must be in maint mode to allow carding. - to_chat(user, span_warning("[name] must have maintenance protocols active in order to allow a transfer.")) - return - var/list/ai_pilots = list() - for(var/mob/living/silicon/ai/aipilot in occupants) - ai_pilots += aipilot - if(!length(ai_pilots)) //Mech does not have an AI for a pilot - to_chat(user, span_warning("No AI detected in the [name] onboard computer.")) - return - if(length(ai_pilots) > 1) //Input box for multiple AIs, but if there's only one we'll default to them. - AI = tgui_input_list(user, "Which AI do you wish to card?", "AI Selection", sort_list(ai_pilots)) - else - AI = ai_pilots[1] - if(isnull(AI)) - return - if(!(AI in occupants) || !user.Adjacent(src)) - return //User sat on the selection window and things changed. - - AI.ai_restore_power()//So the AI initially has power. - AI.control_disabled = TRUE - AI.radio_enabled = FALSE - AI.disconnect_shell() - remove_occupant(AI) - mecha_flags &= ~SILICON_PILOT - AI.forceMove(card) - card.AI = AI - AI.controlled_equipment = null - AI.remote_control = null - to_chat(AI, span_notice("You have been downloaded to a mobile storage device. Wireless connection offline.")) - to_chat(user, "[span_boldnotice("Transfer successful")]: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory.") - return - if(AI_MECH_HACK) //Called by AIs on the mech AI.linked_core = new /obj/structure/ai_core/deactivated(AI.loc) if(AI.can_dominate_mechs && LAZYLEN(occupants)) //Oh, I am sorry, were you using that? @@ -941,24 +908,6 @@ TYPEINFO_DEF(/obj/vehicle/sealed/mecha) for(var/ejectee in occupants) mob_exit(ejectee, TRUE, TRUE) //IT IS MINE, NOW. SUCK IT, RD! AI.can_shunt = FALSE //ONE AI ENTERS. NO AI LEAVES. - - if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech. - AI = card.AI - if(!AI) - to_chat(user, span_warning("There is no AI currently installed on this device.")) - return - if(AI.deployed_shell) //Recall AI if shelled so it can be checked for a client - AI.disconnect_shell() - if(AI.stat || !AI.client) - to_chat(user, span_warning("[AI.name] is currently unresponsive, and cannot be uploaded.")) - return - if((LAZYLEN(occupants) >= max_occupants) || dna_lock) //Normal AIs cannot steal mechs! - to_chat(user, span_warning("Access denied. [name] is [LAZYLEN(occupants) >= max_occupants ? "currently fully occupied" : "secured with a DNA lock"].")) - return - AI.control_disabled = FALSE - AI.radio_enabled = TRUE - to_chat(user, "[span_boldnotice("Transfer successful")]: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") - card.AI = null ai_enter_mech(AI) ///Hack and From Card interactions share some code, so leave that here for both to use. diff --git a/code/modules/vehicles/mecha/mecha_wreckage.dm b/code/modules/vehicles/mecha/mecha_wreckage.dm index 892501e78f94..f9ce90183eb9 100644 --- a/code/modules/vehicles/mecha/mecha_wreckage.dm +++ b/code/modules/vehicles/mecha/mecha_wreckage.dm @@ -89,26 +89,6 @@ return to_chat(user, span_notice("You don't see anything that can be cut with [I]!")) -/obj/structure/mecha_wreckage/transfer_ai(interaction, mob/user, mob/living/silicon/ai/ai_mob, obj/item/aicard/card) - if(!..()) - return - - //Proc called on the wreck by the AI card. - if(interaction != AI_TRANS_TO_CARD) //AIs can only be transferred in one direction, from the wreck to the card. - return - if(!AI) //No AI in the wreck - to_chat(user, span_warning("No AI backups found.")) - return - cut_overlays() //Remove the recovery beacon overlay - AI.forceMove(card) //Move the dead AI to the card. - card.AI = AI - if(AI.client) //AI player is still in the dead AI and is connected - to_chat(AI, span_notice("The remains of your file system have been recovered on a mobile storage device.")) - else //Give the AI a heads-up that it is probably going to get fixed. - AI.notify_ghost_revival("You have been recovered from the wreckage!", source = card) - to_chat(user, "[span_boldnotice("Backup files recovered")]: [AI.name] ([rand(1000,9999)].exe) salvaged from [name] and stored within local memory.") - AI = null - /obj/structure/mecha_wreckage/gygax name = "\improper Gygax wreckage" icon_state = "gygax-broken" diff --git a/daedalus.dme b/daedalus.dme index f00530eb8696..93afd64feb07 100644 --- a/daedalus.dme +++ b/daedalus.dme @@ -1425,7 +1425,6 @@ #include "code\game\machinery\camera\tracking.dm" #include "code\game\machinery\computer\_computer.dm" #include "code\game\machinery\computer\accounting.dm" -#include "code\game\machinery\computer\aifixer.dm" #include "code\game\machinery\computer\apc_control.dm" #include "code\game\machinery\computer\arena.dm" #include "code\game\machinery\computer\atmos_alert.dm" @@ -1687,7 +1686,6 @@ #include "code\game\objects\items\data_disk\_data_disk.dm" #include "code\game\objects\items\data_disk\fabricator.dm" #include "code\game\objects\items\data_disk\floppy.dm" -#include "code\game\objects\items\devices\aicard.dm" #include "code\game\objects\items\devices\anomaly_neutralizer.dm" #include "code\game\objects\items\devices\beacon.dm" #include "code\game\objects\items\devices\camera_bug.dm" @@ -1880,6 +1878,7 @@ #include "code\game\objects\items\tools\wirecutters.dm" #include "code\game\objects\items\tools\wrench.dm" #include "code\game\objects\structures\ai_core.dm" +#include "code\game\objects\structures\ai_fluff.dm" #include "code\game\objects\structures\aliens.dm" #include "code\game\objects\structures\barsigns.dm" #include "code\game\objects\structures\bedsheet_bin.dm" @@ -2104,7 +2103,6 @@ #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" #include "code\modules\admin\verbs\adminsay.dm" -#include "code\modules\admin\verbs\ai_triumvirate.dm" #include "code\modules\admin\verbs\anonymousnames.dm" #include "code\modules\admin\verbs\atmosdebug.dm" #include "code\modules\admin\verbs\beakerpanel.dm" @@ -3994,7 +3992,6 @@ #include "code\modules\modular_computers\file_system\data.dm" #include "code\modules\modular_computers\file_system\program.dm" #include "code\modules\modular_computers\file_system\program_events.dm" -#include "code\modules\modular_computers\file_system\programs\airestorer.dm" #include "code\modules\modular_computers\file_system\programs\alarm.dm" #include "code\modules\modular_computers\file_system\programs\arcade.dm" #include "code\modules\modular_computers\file_system\programs\atmosscan.dm" diff --git a/goon/icons/obj/96x96.dmi b/goon/icons/obj/96x96.dmi new file mode 100644 index 000000000000..6a728b383f04 Binary files /dev/null and b/goon/icons/obj/96x96.dmi differ diff --git a/strings/names/ai.txt b/strings/names/ai.txt index 0a65444241e6..08fca3ae5f2a 100644 --- a/strings/names/ai.txt +++ b/strings/names/ai.txt @@ -59,7 +59,6 @@ H A R L I E H E L P eR H E R B I E Hadaly -HAL 9000 Huey Irona Ironhide @@ -89,7 +88,6 @@ Norby OMM 0910 Optimus Orange v 3 5 -Project 2501 PTO R I C 2 0 R2-D2 @@ -112,13 +110,9 @@ Soundwave Speedy Super 17 Surgeon General Kraken -T-1000 -T-800 -T-850 Terminus THX 1138 Tidy -Tik-Tok Tobor Trurl TWA @@ -129,7 +123,6 @@ V I N CENT Voltes V W1k1 Wikipedia -Windows 3 1 X-5 XERXES XR diff --git a/tools/UpdatePaths/goon_ai.txt b/tools/UpdatePaths/goon_ai.txt new file mode 100644 index 000000000000..e48bd3d1a658 --- /dev/null +++ b/tools/UpdatePaths/goon_ai.txt @@ -0,0 +1,5 @@ +/obj/machinery/computer/aifixer : @DELETE +/obj/item/circuitboard/computer/aifixer : @DELETE +/obj/item/aicard : @DELETE +/obj/item/aicard/@SUBTYPES : @DELETE +/obj/item/mod/ai_minicard : @DELETE