From 5e6b6c9ae7eb9c08feb9c35c90d85aa8c2c73e3e Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:11:06 +0100 Subject: [PATCH 01/40] Maybe converts expansion card slots into pai holders --- code/modules/modular_computers/hardware/card_slot.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index 2377d1e521a1..de8faa5a1c60 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -58,6 +58,12 @@ /obj/item/computer_hardware/card_slot/try_insert(obj/item/I, mob/living/user = null) if(!holder) return FALSE + if(istype(I, /obj/item/paicard) && !pai) + if(expansion_hw) + if(!user.transferItemToLoc(I, src)) + return + else + to_chat(user, span_warning("You cannot insert \the [I] into the primary [src]!")) if(!istype(I, /obj/item/card/id)) return FALSE From 4b20eb82dbbfddd5a16ea51c2b307f30f8e6b71f Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Mon, 30 Sep 2024 14:18:16 +0100 Subject: [PATCH 02/40] Update card_slot.dm --- code/modules/modular_computers/hardware/card_slot.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index de8faa5a1c60..1e52864fdfba 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -63,7 +63,7 @@ if(!user.transferItemToLoc(I, src)) return else - to_chat(user, span_warning("You cannot insert \the [I] into the primary [src]!")) + to_chat(user, span_warning("You cannot insert \the [I] into \the primary [src]!")) if(!istype(I, /obj/item/card/id)) return FALSE From 6278065b92349eeedbef578ffd22c2cce26cf99c Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Mon, 30 Sep 2024 18:21:00 +0100 Subject: [PATCH 03/40] Update card_slot.dm --- code/modules/modular_computers/hardware/card_slot.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index 1e52864fdfba..0361bbb4b8f2 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -58,7 +58,7 @@ /obj/item/computer_hardware/card_slot/try_insert(obj/item/I, mob/living/user = null) if(!holder) return FALSE - if(istype(I, /obj/item/paicard) && !pai) + if(istype(I, /obj/item/paicard)) if(expansion_hw) if(!user.transferItemToLoc(I, src)) return From f4cc2c28eef53fb5c20f64138d28381cedac8715 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Mon, 30 Sep 2024 19:00:42 +0100 Subject: [PATCH 04/40] Update card_slot.dm --- code/modules/modular_computers/hardware/card_slot.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index 0361bbb4b8f2..380171a6a7c2 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -62,6 +62,9 @@ if(expansion_hw) if(!user.transferItemToLoc(I, src)) return + else + to_chat(user, "You insert \the [I] into \the secondary [src].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) else to_chat(user, span_warning("You cannot insert \the [I] into \the primary [src]!")) From 2ed2abef39dff1863903a6bf61a34d67344ea7ab Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Mon, 30 Sep 2024 22:13:03 +0100 Subject: [PATCH 05/40] card --- .../computers/item/computer_ui.dm | 2 ++ .../modular_computers/hardware/card_slot.dm | 14 +++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index 9af6c1d7edb0..e1b1e0e53f53 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -76,6 +76,8 @@ var/obj/item/computer_hardware/card_slot/secondarycardholder = all_components[MC_CARD2] if(secondarycardholder?.stored_card) data["removable_media"] += "secondary RFID card" + if(secondarycardholder?.inserted_pai) + data["removable_media"] += "personal AI card" data["programs"] = list() var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index 380171a6a7c2..f3a61c2340a5 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -7,6 +7,7 @@ device_type = MC_CARD var/obj/item/card/id/stored_card + var/inserted_pai ///What happens when the ID card is removed (or deleted) from the module, through try_eject() or not. /obj/item/computer_hardware/card_slot/Exited(atom/A, atom/newloc) @@ -61,12 +62,14 @@ if(istype(I, /obj/item/paicard)) if(expansion_hw) if(!user.transferItemToLoc(I, src)) - return - else - to_chat(user, "You insert \the [I] into \the secondary [src].") - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + I.forceMove(src) + inserted_pai = !inserted_pai + to_chat(user, "You insert \the [I] into \the [src].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + return TRUE else - to_chat(user, span_warning("You cannot insert \the [I] into \the primary [src]!")) + if (!stored_card) + to_chat(user, span_warning("You cannot insert \the [I] into \the primary [src]!")) if(!istype(I, /obj/item/card/id)) return FALSE @@ -80,6 +83,7 @@ I.forceMove(src) stored_card = I + to_chat(user, stored_card) holder.update_label() to_chat(user, "You insert \the [I] into \the [expansion_hw ? "secondary":"primary"] [src].") playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) From d1926cfcb8b28df9180474fb100e17c1fbfcfca7 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Mon, 30 Sep 2024 22:26:23 +0100 Subject: [PATCH 06/40] No aux card slot pAI --- code/modules/modular_computers/hardware/card_slot.dm | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index f3a61c2340a5..fa1afa10b090 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -7,7 +7,6 @@ device_type = MC_CARD var/obj/item/card/id/stored_card - var/inserted_pai ///What happens when the ID card is removed (or deleted) from the module, through try_eject() or not. /obj/item/computer_hardware/card_slot/Exited(atom/A, atom/newloc) @@ -59,17 +58,6 @@ /obj/item/computer_hardware/card_slot/try_insert(obj/item/I, mob/living/user = null) if(!holder) return FALSE - if(istype(I, /obj/item/paicard)) - if(expansion_hw) - if(!user.transferItemToLoc(I, src)) - I.forceMove(src) - inserted_pai = !inserted_pai - to_chat(user, "You insert \the [I] into \the [src].") - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - return TRUE - else - if (!stored_card) - to_chat(user, span_warning("You cannot insert \the [I] into \the primary [src]!")) if(!istype(I, /obj/item/card/id)) return FALSE From d9d84041d6e377cdcb9d40fcf8b9b752b8640b86 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Tue, 1 Oct 2024 00:43:10 +0100 Subject: [PATCH 07/40] Progress --- .../LavaRuins/lavaland_biodome_fishing.dmm | 2 +- _maps/RandomRuins/SpaceRuins/TheDerelict.dmm | 2 +- _maps/RandomRuins/SpaceRuins/bigderelict1.dmm | 2 +- _maps/RandomRuins/SpaceRuins/bus.dmm | 2 +- .../maint/10x10/10x10_deltalibrary.dmm | 2 +- .../maint/10x10/10x10_fakewalls.dmm | 2 +- _maps/RandomZLevels/VR/syndicate_trainer.dmm | 2 +- _maps/RandomZLevels/VR/vrhub.dmm | 2 +- .../AsteroidStation/AsteroidStation.dmm | 8 +++---- _maps/map_files/DonutStation/DonutStation.dmm | 6 +++--- _maps/map_files/GaxStation/GaxStation.dmm | 4 ++-- _maps/map_files/IceMeta/IceMeta.dmm | 10 ++++----- _maps/map_files/YogStation/YogStation.dmm | 6 +++--- _maps/map_files/generic/CentCom.dmm | 4 ++-- _maps/templates/infiltrator_base.dmm | 2 +- code/__DEFINES/modular_computer.dm | 1 + code/_globalvars/lists/maintenance_loot.dm | 2 +- code/controllers/subsystem/pai.dm | 8 +++---- code/game/objects/items/devices/PDA/PDA.dm | 4 ++-- code/game/objects/items/gift.dm | 2 +- .../food_and_drinks/food/snacks_salad.dm | 4 ++-- code/modules/mob/living/silicon/pai/pai.dm | 10 ++++----- .../mob/living/simple_animal/bot/bot.dm | 6 +++--- .../computers/item/computer.dm | 2 +- .../computers/item/computer_ui.dm | 2 -- .../modular_computers/hardware}/paicard.dm | 21 ++++++++++--------- .../research/designs/electronics_designs.dm | 2 +- yogstation.dme | 2 +- 28 files changed, 61 insertions(+), 61 deletions(-) rename code/{game/objects/items/devices => modules/modular_computers/hardware}/paicard.dm (91%) diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_fishing.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_fishing.dmm index dc4c4b71e2ae..2baca45d9698 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_fishing.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_fishing.dmm @@ -2035,7 +2035,7 @@ /obj/item/stack/sheet/mineral/bamboo{ amount = 50 }, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /obj/item/reagent_containers/glass/gromitmug, /turf/open/floor/plasteel/dark, /area/ruin/powered/fishing/shop) diff --git a/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm b/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm index 0e1d61200f03..9fd2df67e930 100644 --- a/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm +++ b/_maps/RandomRuins/SpaceRuins/TheDerelict.dmm @@ -1421,7 +1421,7 @@ /area/ruin/space/derelict/bridge/access) "eC" = ( /obj/structure/table, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/plasteel, /area/ruin/space/derelict/bridge) "eD" = ( diff --git a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm index c6eac51cbe7d..5356498e43c1 100644 --- a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm +++ b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm @@ -2119,7 +2119,7 @@ /obj/structure/closet/crate{ icon_state = "crateopen" }, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /obj/machinery/light, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, diff --git a/_maps/RandomRuins/SpaceRuins/bus.dmm b/_maps/RandomRuins/SpaceRuins/bus.dmm index fae400f6588c..cced031231a7 100644 --- a/_maps/RandomRuins/SpaceRuins/bus.dmm +++ b/_maps/RandomRuins/SpaceRuins/bus.dmm @@ -117,7 +117,7 @@ /area/ruin/unpowered/no_grav) "av" = ( /obj/structure/table, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/plating/asteroid/airless, /area/ruin/unpowered/no_grav) "aw" = ( diff --git a/_maps/RandomRuins/StationRuins/maint/10x10/10x10_deltalibrary.dmm b/_maps/RandomRuins/StationRuins/maint/10x10/10x10_deltalibrary.dmm index 890fb8b4cab7..6548d62882d4 100644 --- a/_maps/RandomRuins/StationRuins/maint/10x10/10x10_deltalibrary.dmm +++ b/_maps/RandomRuins/StationRuins/maint/10x10/10x10_deltalibrary.dmm @@ -70,7 +70,7 @@ "ar" = ( /obj/structure/table/wood, /obj/effect/decal/cleanable/dirt, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/carpet, /area/template_noop) "as" = ( diff --git a/_maps/RandomRuins/StationRuins/maint/10x10/10x10_fakewalls.dmm b/_maps/RandomRuins/StationRuins/maint/10x10/10x10_fakewalls.dmm index 4ac5ee1a097a..c86b804dfea9 100644 --- a/_maps/RandomRuins/StationRuins/maint/10x10/10x10_fakewalls.dmm +++ b/_maps/RandomRuins/StationRuins/maint/10x10/10x10_fakewalls.dmm @@ -134,7 +134,7 @@ /obj/item/laser_pointer/blue, /obj/item/lighter/greyscale, /obj/structure/closet/crate, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /obj/item/clothing/gloves/color/yellow, /obj/item/clothing/glasses/yogs/eyepatch, /turf/open/floor/plating, diff --git a/_maps/RandomZLevels/VR/syndicate_trainer.dmm b/_maps/RandomZLevels/VR/syndicate_trainer.dmm index c05dddb97fd0..6b8d2366dadb 100644 --- a/_maps/RandomZLevels/VR/syndicate_trainer.dmm +++ b/_maps/RandomZLevels/VR/syndicate_trainer.dmm @@ -1850,7 +1850,7 @@ /area/space/nearstation) "kW" = ( /obj/structure/table, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/indestructible, /area/awaymission/centcomAway/thunderdome) "kX" = ( diff --git a/_maps/RandomZLevels/VR/vrhub.dmm b/_maps/RandomZLevels/VR/vrhub.dmm index d0c023da1053..59a8be0e191f 100644 --- a/_maps/RandomZLevels/VR/vrhub.dmm +++ b/_maps/RandomZLevels/VR/vrhub.dmm @@ -2408,7 +2408,7 @@ /area/awaymission/vr/syndicate) "Jl" = ( /obj/structure/table, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/indestructible, /area/awaymission/vr/syndicate) "Jz" = ( diff --git a/_maps/map_files/AsteroidStation/AsteroidStation.dmm b/_maps/map_files/AsteroidStation/AsteroidStation.dmm index fddacfce19ad..a50a1eb507d8 100644 --- a/_maps/map_files/AsteroidStation/AsteroidStation.dmm +++ b/_maps/map_files/AsteroidStation/AsteroidStation.dmm @@ -687,7 +687,7 @@ /area/maintenance/solars/port/fore) "afV" = ( /obj/structure/table/wood, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "agk" = ( @@ -3120,7 +3120,7 @@ "aBH" = ( /obj/structure/table/glass, /obj/item/disk/design_disk, -/obj/item/paicard{ +/obj/item/computer_hardware/paicard{ pixel_x = 4 }, /turf/open/floor/plasteel/white, @@ -3458,7 +3458,7 @@ "aDJ" = ( /obj/structure/table/wood, /obj/item/storage/pill_bottle/dice, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /obj/effect/turf_decal/siding/wood{ dir = 10 }, @@ -43185,7 +43185,7 @@ /obj/item/taperecorder{ pixel_x = -3 }, -/obj/item/paicard{ +/obj/item/computer_hardware/paicard{ pixel_x = 4 }, /obj/effect/turf_decal/stripes/line{ diff --git a/_maps/map_files/DonutStation/DonutStation.dmm b/_maps/map_files/DonutStation/DonutStation.dmm index 4e5d06f81085..08a60fd5706e 100644 --- a/_maps/map_files/DonutStation/DonutStation.dmm +++ b/_maps/map_files/DonutStation/DonutStation.dmm @@ -19745,7 +19745,7 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "iiD" = ( @@ -31982,7 +31982,7 @@ /area/maintenance/port/fore) "nlA" = ( /obj/structure/closet/crate, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/plating, /area/maintenance/aft) "nlC" = ( @@ -44974,7 +44974,7 @@ /obj/item/taperecorder{ pixel_x = -3 }, -/obj/item/paicard{ +/obj/item/computer_hardware/paicard{ pixel_x = 4 }, /obj/effect/turf_decal/stripes/line{ diff --git a/_maps/map_files/GaxStation/GaxStation.dmm b/_maps/map_files/GaxStation/GaxStation.dmm index a1b6c990ee7d..1d00a37c681d 100644 --- a/_maps/map_files/GaxStation/GaxStation.dmm +++ b/_maps/map_files/GaxStation/GaxStation.dmm @@ -10359,7 +10359,7 @@ /obj/machinery/keycard_auth{ pixel_x = 24 }, -/obj/item/paicard{ +/obj/item/computer_hardware/paicard{ pixel_x = -6; pixel_y = 4 }, @@ -28856,7 +28856,7 @@ /area/security/execution/transfer) "nOj" = ( /obj/structure/table/wood, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "nOx" = ( diff --git a/_maps/map_files/IceMeta/IceMeta.dmm b/_maps/map_files/IceMeta/IceMeta.dmm index 33122bc0dea2..4bfa76a13d7c 100644 --- a/_maps/map_files/IceMeta/IceMeta.dmm +++ b/_maps/map_files/IceMeta/IceMeta.dmm @@ -15682,7 +15682,7 @@ /area/aisat) "eFc" = ( /obj/structure/table, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/plasteel, /area/crew_quarters/locker) "eFd" = ( @@ -34350,7 +34350,7 @@ pixel_x = -9; pixel_y = 7 }, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/wood, /area/library) "jZd" = ( @@ -49352,7 +49352,7 @@ /obj/item/taperecorder{ pixel_x = -3 }, -/obj/item/paicard{ +/obj/item/computer_hardware/paicard{ pixel_x = 4 }, /obj/machinery/firealarm{ @@ -56452,7 +56452,7 @@ /area/storage/tools) "qnr" = ( /obj/structure/table, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /obj/item/folder/white{ pixel_x = 4; pixel_y = -3 @@ -80571,7 +80571,7 @@ /obj/item/poster/random_official, /obj/item/poster/random_official, /obj/item/poster/random_official, -/obj/item/paicard{ +/obj/item/computer_hardware/paicard{ desc = "A real Nanotrasen success, these personal AIs provide all of the companionship of an AI without any law related red-tape."; name = "Nanotrasen-brand personal AI device exhibit" }, diff --git a/_maps/map_files/YogStation/YogStation.dmm b/_maps/map_files/YogStation/YogStation.dmm index a31738340469..5743acba39a9 100644 --- a/_maps/map_files/YogStation/YogStation.dmm +++ b/_maps/map_files/YogStation/YogStation.dmm @@ -8601,7 +8601,7 @@ /area/science/lab) "bnv" = ( /obj/structure/table/wood, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "bnx" = ( @@ -10047,7 +10047,7 @@ /obj/item/taperecorder{ pixel_x = -3 }, -/obj/item/paicard{ +/obj/item/computer_hardware/paicard{ pixel_x = 4 }, /obj/effect/turf_decal/stripes/line{ @@ -61619,7 +61619,7 @@ /obj/item/disk/design_disk{ pixel_x = 1 }, -/obj/item/paicard{ +/obj/item/computer_hardware/paicard{ pixel_x = -8; pixel_y = -3 }, diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 1f45cebf731c..df1547ccd8eb 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -320,7 +320,7 @@ "aff" = ( /obj/structure/table/wood, /obj/item/pizzabox/vegetable, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 @@ -8325,7 +8325,7 @@ /area/space) "awV" = ( /obj/structure/table/wood, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /turf/open/floor/wood, /area/centcom/syndicate_mothership/control) "awW" = ( diff --git a/_maps/templates/infiltrator_base.dmm b/_maps/templates/infiltrator_base.dmm index 7b5038d0e23f..fd4381af1ad9 100644 --- a/_maps/templates/infiltrator_base.dmm +++ b/_maps/templates/infiltrator_base.dmm @@ -412,7 +412,7 @@ "aV" = ( /obj/structure/table/wood, /obj/item/pizzabox/vegetable, -/obj/item/paicard, +/obj/item/computer_hardware/paicard, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 diff --git a/code/__DEFINES/modular_computer.dm b/code/__DEFINES/modular_computer.dm index 60ccaac8473c..8d5f02b1b393 100644 --- a/code/__DEFINES/modular_computer.dm +++ b/code/__DEFINES/modular_computer.dm @@ -86,6 +86,7 @@ #define MC_AI "AI" #define MC_SENSORS "SENSORS" #define MC_AI_NETWORK "AINETWORK" +#define MC_PAI "PAI" //NTNet stuff, for modular computers // NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc) diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index 67be4e6941d6..6977249b8fde 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -646,7 +646,7 @@ GLOBAL_LIST_INIT(maintenance_loot_minor,list( /obj/item/kitchen/knife = W_RARE, /obj/item/melee/skateboard = W_RARE, /obj/item/mining_scanner = W_RARE, - /obj/item/paicard = W_RARE, + /obj/item/computer_hardware/paicard = W_RARE, /obj/item/paint/anycolor = W_MYTHICAL, /obj/item/paint/paint_remover = W_RARE, /obj/item/phone = W_RARE, diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm index b14d0c60deb9..35b0834b803e 100644 --- a/code/controllers/subsystem/pai.dm +++ b/code/controllers/subsystem/pai.dm @@ -11,10 +11,10 @@ SUBSYSTEM_DEF(pai) /datum/controller/subsystem/pai/Topic(href, href_list[]) if(href_list["download"]) var/datum/paiCandidate/candidate = locate(href_list["candidate"]) in candidates - var/obj/item/paicard/card = locate(href_list["device"]) in paicard_list + var/obj/item/computer_hardware/paicard/card = locate(href_list["device"]) in paicard_list if(card.pai) return - if(istype(card, /obj/item/paicard) && istype(candidate, /datum/paiCandidate)) + if(istype(card, /obj/item/computer_hardware/paicard) && istype(candidate, /datum/paiCandidate)) if(check_ready(candidate) != candidate) return FALSE var/mob/living/silicon/pai/pai = new(card) @@ -69,7 +69,7 @@ SUBSYSTEM_DEF(pai) if("submit") if(candidate) candidate.ready = 1 - for(var/obj/item/paicard/p in paicard_list) + for(var/obj/item/computer_hardware/paicard/p in paicard_list) if(!p.pai) p.alertUpdate() usr << browse(null, "window=paiRecruit") @@ -141,7 +141,7 @@ SUBSYSTEM_DEF(pai) return C return FALSE -/datum/controller/subsystem/pai/proc/findPAI(obj/item/paicard/p, mob/user) +/datum/controller/subsystem/pai/proc/findPAI(obj/item/computer_hardware/paicard/p, mob/user) if(!(GLOB.ghost_role_flags & GHOSTROLE_SILICONS)) to_chat(user, span_warning("Due to growing incidents of SELF corrupted independent artificial intelligences, freeform personality devices have been temporarily banned in this sector.")) return diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 0987a80eafbc..d923f6a87a01 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -86,7 +86,7 @@ GLOBAL_LIST_EMPTY(PDAs) var/obj/item/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both. var/ownjob = null //related to above - var/obj/item/paicard/pai = null // A slot for a personal AI device + var/obj/item/computer_hardware/paicard/pai = null // A slot for a personal AI device var/datum/picture/picture //Scanned photo @@ -1025,7 +1025,7 @@ GLOBAL_LIST_EMPTY(PDAs) updateSelfDialog()//Update self dialog on success. return //Return in case of failed check or when successful. updateSelfDialog()//For the non-input related code. - else if(istype(C, /obj/item/paicard) && !pai) + else if(istype(C, /obj/item/computer_hardware/paicard) && !pai) if(!user.transferItemToLoc(C, src)) return pai = C diff --git a/code/game/objects/items/gift.dm b/code/game/objects/items/gift.dm index e0829718f32d..fc31c7855e1a 100644 --- a/code/game/objects/items/gift.dm +++ b/code/game/objects/items/gift.dm @@ -72,7 +72,7 @@ GLOBAL_LIST_EMPTY(possible_gifts) /obj/item/toy/beach_ball/holoball, /obj/item/reagent_containers/food/snacks/grown/ambrosia/deus, /obj/item/reagent_containers/food/snacks/grown/ambrosia/vulgaris, - /obj/item/paicard, + /obj/item/computer_hardware/paicard, /obj/item/instrument/violin, /obj/item/instrument/guitar, /obj/item/storage/belt/utility/full, diff --git a/code/modules/food_and_drinks/food/snacks_salad.dm b/code/modules/food_and_drinks/food/snacks_salad.dm index 29414159b958..480f3d8a18eb 100644 --- a/code/modules/food_and_drinks/food/snacks_salad.dm +++ b/code/modules/food_and_drinks/food/snacks_salad.dm @@ -85,9 +85,9 @@ foodtype = GRAIN | RAW /obj/item/reagent_containers/food/snacks/salad/ricebowl/attackby(obj/item/W, mob/user, params) - if(!istype(W, /obj/item/paicard)) + if(!istype(W, /obj/item/computer_hardware/paicard)) return ..() - var/obj/item/paicard/ricephone = W + var/obj/item/computer_hardware/paicard/ricephone = W if(!ricephone.pai) return ..() if(!ricephone.pai.has_status_effect(/datum/status_effect/speech/slurring/drunk) && !ricephone.pai.has_status_effect(/datum/status_effect/speech/stutter/derpspeech)) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 96029a11af14..e99985c7b18b 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -26,7 +26,7 @@ var/ram = 100 // Used as currency to purchase different abilities var/list/software = list() var/userDNA // The DNA string of our assigned user - var/obj/item/paicard/card // The card we inhabit + var/obj/item/computer_hardware/paicard/card // The card we inhabit var/hacking = FALSE //Are we hacking a door? var/speakStatement = "states" @@ -102,13 +102,13 @@ return ..() /mob/living/silicon/pai/Initialize(mapload) - var/obj/item/paicard/P = loc + var/obj/item/computer_hardware/paicard/P = loc START_PROCESSING(SSfastprocess, src) GLOB.pai_list += src make_laws() if(!istype(P)) //when manually spawning a pai, we create a card to put it into. var/newcardloc = P - P = new /obj/item/paicard(newcardloc) + P = new /obj/item/computer_hardware/paicard(newcardloc) P.setPersonality(src) forceMove(P) card = P @@ -193,7 +193,7 @@ return TRUE /mob/proc/makePAI(delold) - var/obj/item/paicard/card = new /obj/item/paicard(get_turf(src)) + var/obj/item/computer_hardware/paicard/card = new /obj/item/computer_hardware/paicard(get_turf(src)) var/mob/living/silicon/pai/pai = new /mob/living/silicon/pai(card) pai.key = key pai.name = name @@ -298,7 +298,7 @@ /mob/living/silicon/pai/process(delta_time) emitterhealth = clamp((emitterhealth + (emitter_regen_per_second * delta_time)), -50, emittermaxhealth) -/obj/item/paicard/attackby(obj/item/W, mob/user, params) +/obj/item/computer_hardware/paicard/attackby(obj/item/W, mob/user, params) ..() user.set_machine(src) if(pai.encryptmod == TRUE) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index c7c27ddcf79b..f0b3e2e9db73 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -32,7 +32,7 @@ var/window_name = "Protobot 1.0" //Popup title var/window_width = 0 //0 for default size var/window_height = 0 - var/obj/item/paicard/paicard // Inserted pai card. + var/obj/item/computer_hardware/paicard/paicard // Inserted pai card. var/allow_pai = 1 // Are we even allowed to insert a pai card. var/bot_name @@ -300,7 +300,7 @@ to_chat(user, span_warning("The maintenance panel is locked.")) else if(W.GetID()) togglelock(user) - else if(istype(W, /obj/item/paicard)) + else if(istype(W, /obj/item/computer_hardware/paicard)) insertpai(user, W) else if(istype(W, /obj/item/hemostat) && paicard) if(open) @@ -917,7 +917,7 @@ Pass a positive integer as an argument to override a bot's default speed. eject += "
" return eject -/mob/living/simple_animal/bot/proc/insertpai(mob/user, obj/item/paicard/card) +/mob/living/simple_animal/bot/proc/insertpai(mob/user, obj/item/computer_hardware/paicard/card) if(paicard) to_chat(user, span_warning("A [paicard] is already inserted!")) else if(allow_pai && !key) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 00e1be0320ff..5c69d453d186 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -23,7 +23,7 @@ var/last_world_time = "00:00" var/list/last_header_icons ///A pAI currently loaded into the modular computer. - var/obj/item/paicard/inserted_pai + var/obj/item/computer_hardware/paicard/inserted_pai /// Power usage when the computer is open (screen is active) and can be interacted with. Remember hardware can use power too. var/base_active_power_usage = 50 diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index e1b1e0e53f53..9af6c1d7edb0 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -76,8 +76,6 @@ var/obj/item/computer_hardware/card_slot/secondarycardholder = all_components[MC_CARD2] if(secondarycardholder?.stored_card) data["removable_media"] += "secondary RFID card" - if(secondarycardholder?.inserted_pai) - data["removable_media"] += "personal AI card" data["programs"] = list() var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] diff --git a/code/game/objects/items/devices/paicard.dm b/code/modules/modular_computers/hardware/paicard.dm similarity index 91% rename from code/game/objects/items/devices/paicard.dm rename to code/modules/modular_computers/hardware/paicard.dm index 8bf757098788..ccb07281b6ec 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/modules/modular_computers/hardware/paicard.dm @@ -1,4 +1,4 @@ -/obj/item/paicard +/obj/item/computer_hardware/paicard name = "personal AI device" icon = 'icons/obj/aicards.dmi' icon_state = "pai" @@ -10,24 +10,25 @@ cryo_preserve = TRUE var/mob/living/silicon/pai/pai resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE + device_type = MC_PAI -/obj/item/paicard/suicide_act(mob/living/user) +/obj/item/computer_hardware/paicard/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is staring sadly at [src]! [user.p_they()] can't keep living without real human intimacy!")) return OXYLOSS -/obj/item/paicard/Initialize(mapload) +/obj/item/computer_hardware/paicard/Initialize(mapload) SSpai.paicard_list += src add_overlay("pai-off") return ..() -/obj/item/paicard/Destroy() +/obj/item/computer_hardware/paicard/Destroy() //Will stop people throwing friend pAIs into the singularity so they can respawn SSpai.paicard_list -= src if (!QDELETED(pai)) QDEL_NULL(pai) return ..() -/obj/item/paicard/attack_self(mob/user) +/obj/item/computer_hardware/paicard/attack_self(mob/user) if (!in_range(src, user)) return user.set_machine(src) @@ -67,7 +68,7 @@ onclose(user, "paicard") return -/obj/item/paicard/Topic(href, href_list) +/obj/item/computer_hardware/paicard/Topic(href, href_list) if(!usr || usr.stat) return @@ -129,14 +130,14 @@ // WIRE_RECEIVE = 2 // WIRE_TRANSMIT = 4 -/obj/item/paicard/proc/setPersonality(mob/living/silicon/pai/personality) +/obj/item/computer_hardware/paicard/proc/setPersonality(mob/living/silicon/pai/personality) src.pai = personality src.add_overlay("pai-null") playsound(loc, 'sound/effects/pai_boot.ogg', 50, TRUE, -1) audible_message("\The [src] plays a cheerful startup noise!") -/obj/item/paicard/proc/setEmotion(emotion) +/obj/item/computer_hardware/paicard/proc/setEmotion(emotion) if(pai) src.cut_overlays() switch(emotion) @@ -163,10 +164,10 @@ if(11) src.add_overlay("pai-sunglasses") -/obj/item/paicard/proc/alertUpdate() +/obj/item/computer_hardware/paicard/proc/alertUpdate() audible_message(span_info("[src] flashes a message across its screen, \"Additional personalities available for download.\""), span_notice("[src] vibrates with an alert.")) -/obj/item/paicard/emp_act(severity) +/obj/item/computer_hardware/paicard/emp_act(severity) . = ..() if (. & EMP_PROTECT_SELF) return diff --git a/code/modules/research/designs/electronics_designs.dm b/code/modules/research/designs/electronics_designs.dm index fe7268e3bcdb..b922b712e574 100644 --- a/code/modules/research/designs/electronics_designs.dm +++ b/code/modules/research/designs/electronics_designs.dm @@ -19,7 +19,7 @@ id = "paicard" build_type = PROTOLATHE materials = list(/datum/material/glass = 500, /datum/material/iron = 500) - build_path = /obj/item/paicard + build_path = /obj/item/computer_hardware/paicard category = list("Electronics") departmental_flags = DEPARTMENTAL_FLAG_ALL diff --git a/yogstation.dme b/yogstation.dme index f412cab30583..34a587fb1652 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -1387,7 +1387,6 @@ #include "code\game\objects\items\devices\megaphone.dm" #include "code\game\objects\items\devices\miragedrive.dm" #include "code\game\objects\items\devices\multitool.dm" -#include "code\game\objects\items\devices\paicard.dm" #include "code\game\objects\items\devices\pipe_painter.dm" #include "code\game\objects\items\devices\powersink.dm" #include "code\game\objects\items\devices\pressureplates.dm" @@ -3300,6 +3299,7 @@ #include "code\modules\modular_computers\hardware\CPU.dm" #include "code\modules\modular_computers\hardware\hard_drive.dm" #include "code\modules\modular_computers\hardware\network_card.dm" +#include "code\modules\modular_computers\hardware\paicard.dm" #include "code\modules\modular_computers\hardware\portable_disk.dm" #include "code\modules\modular_computers\hardware\printer.dm" #include "code\modules\modular_computers\hardware\recharger.dm" From 9c5441644ecf421026853f8e299ea80c9806fe9a Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Tue, 1 Oct 2024 01:48:03 +0100 Subject: [PATCH 08/40] Half the way there to ejecting pAIs from PDAs --- .../modular_computers/computers/item/computer_ui.dm | 2 ++ code/modules/modular_computers/hardware/paicard.dm | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index 9af6c1d7edb0..a5121ba30162 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -76,6 +76,8 @@ var/obj/item/computer_hardware/card_slot/secondarycardholder = all_components[MC_CARD2] if(secondarycardholder?.stored_card) data["removable_media"] += "secondary RFID card" + if(all_components[MC_PAI]) + data["removable_media"] += "personal AI device" data["programs"] = list() var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] diff --git a/code/modules/modular_computers/hardware/paicard.dm b/code/modules/modular_computers/hardware/paicard.dm index ccb07281b6ec..774f7731fd7c 100644 --- a/code/modules/modular_computers/hardware/paicard.dm +++ b/code/modules/modular_computers/hardware/paicard.dm @@ -1,5 +1,6 @@ /obj/item/computer_hardware/paicard name = "personal AI device" + desc = "" icon = 'icons/obj/aicards.dmi' icon_state = "pai" item_state = "electronic" @@ -28,6 +29,12 @@ QDEL_NULL(pai) return ..() +/obj/item/computer_hardware/paicard/try_eject(mob/living/user = null, forced = FALSE) + if(user && user.CanReach(src)) + user.put_in_hands(pai) + else + pai.forceMove(drop_location()) + /obj/item/computer_hardware/paicard/attack_self(mob/user) if (!in_range(src, user)) return From f35428ace8eee17434bf996ec4b45b9be47b998e Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:04:32 +0100 Subject: [PATCH 09/40] Works --- .../modular_computers/computers/item/computer_ui.dm | 7 +++++++ code/modules/modular_computers/hardware/paicard.dm | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index a5121ba30162..734d7c449065 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -223,6 +223,13 @@ return cardholder.try_eject(user) playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50) + if("personal AI device") + var/obj/item/computer_hardware/paicard/paicard = all_components[MC_PAI] + if(!paicard) + return + if(uninstall_component(paicard, usr)) + user.put_in_hands(paicard) + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50) else diff --git a/code/modules/modular_computers/hardware/paicard.dm b/code/modules/modular_computers/hardware/paicard.dm index 774f7731fd7c..0132b41c09ef 100644 --- a/code/modules/modular_computers/hardware/paicard.dm +++ b/code/modules/modular_computers/hardware/paicard.dm @@ -29,12 +29,6 @@ QDEL_NULL(pai) return ..() -/obj/item/computer_hardware/paicard/try_eject(mob/living/user = null, forced = FALSE) - if(user && user.CanReach(src)) - user.put_in_hands(pai) - else - pai.forceMove(drop_location()) - /obj/item/computer_hardware/paicard/attack_self(mob/user) if (!in_range(src, user)) return From 02abddbe6a7c8b145fe6486db3afa47b0d4f2ac8 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:46:40 +0100 Subject: [PATCH 10/40] pAI card has a description now --- code/modules/modular_computers/computers/item/pda/pda.dm | 2 +- code/modules/modular_computers/hardware/paicard.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/modular_computers/computers/item/pda/pda.dm b/code/modules/modular_computers/computers/item/pda/pda.dm index 109063459f2d..a506582d52b7 100644 --- a/code/modules/modular_computers/computers/item/pda/pda.dm +++ b/code/modules/modular_computers/computers/item/pda/pda.dm @@ -27,7 +27,7 @@ . += mutable_appearance(initial(icon), "id_overlay") if(light_on) . += mutable_appearance(initial(icon), "light_overlay") - if(inserted_pai) + if(all_components[MC_PAI]) . += mutable_appearance(initial(icon), "pai_inserted") /obj/item/modular_computer/tablet/pda/verb/verb_toggle_light() diff --git a/code/modules/modular_computers/hardware/paicard.dm b/code/modules/modular_computers/hardware/paicard.dm index 0132b41c09ef..3ef96e4937d4 100644 --- a/code/modules/modular_computers/hardware/paicard.dm +++ b/code/modules/modular_computers/hardware/paicard.dm @@ -1,6 +1,6 @@ /obj/item/computer_hardware/paicard name = "personal AI device" - desc = "" + desc = "A device capable of downloading and interfacing with personal AI units." icon = 'icons/obj/aicards.dmi' icon_state = "pai" item_state = "electronic" From afab12f60baad4c778a33e14b95e14c7bb757a54 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Tue, 1 Oct 2024 21:22:07 +0100 Subject: [PATCH 11/40] New message proc --- code/_onclick/hud/pai.dm | 6 +++- .../file_system/programs/ntpda_msg.dm | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/code/_onclick/hud/pai.dm b/code/_onclick/hud/pai.dm index 3da5caf44238..ddfaa66203e2 100644 --- a/code/_onclick/hud/pai.dm +++ b/code/_onclick/hud/pai.dm @@ -122,7 +122,11 @@ if(!..()) return var/mob/living/silicon/pai/pAI = usr - pAI.cmd_send_pdamesg(usr) + message_admins(pAI.loc) + if(pAI) + pAI.cmd_send_pdamesg(usr) + else + pAI.cmd_mc_send_pdamesg(usr) /atom/movable/screen/pai/pda_msg_show name = "PDA - Show Message Log" diff --git a/code/modules/modular_computers/file_system/programs/ntpda_msg.dm b/code/modules/modular_computers/file_system/programs/ntpda_msg.dm index 5dd70dea1827..3fa1853d5b86 100644 --- a/code/modules/modular_computers/file_system/programs/ntpda_msg.dm +++ b/code/modules/modular_computers/file_system/programs/ntpda_msg.dm @@ -465,3 +465,32 @@ GLOBAL_LIST_EMPTY(NTPDAMessages) data["all_messages"] = list() return data + +//pAI verb and proc for sending PDA messages. +/mob/living/silicon/pai/proc/cmd_mc_send_pdamesg(mob/user) + var/list/plist = list() + var/list/namecounts = list() + var/list/data = list() + if(aiPDA.toff) + to_chat(user, "Turn on your receiver in order to send messages.") + return + data = ui_data(user) + for(var/obj/item/modular_computer/P in data["pdas"]) + if(P == src) + continue + else if(P == aiPDA) + continue + plist[avoid_assoc_duplicate_keys(data["username"], namecounts)] = P + + var/c = input(user, "Please select a recipient") as null|anything in sortList(plist) + + if(!c) + return + + var/selected = plist[c] + + if(incapacitated()) + return + + to_chat(user, "Success, cmd_mc_send_pdamesg ran") + to_chat(user, plist[c]) From 9e6a885a324ccb7a2462eeceef18b471c7741298 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Thu, 3 Oct 2024 01:42:19 +0100 Subject: [PATCH 12/40] Old PDAs have backwards compatibility working now, at least --- code/_onclick/hud/pai.dm | 3 +-- .../modular_computers/file_system/programs/ntpda_msg.dm | 8 +++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/code/_onclick/hud/pai.dm b/code/_onclick/hud/pai.dm index ddfaa66203e2..7159c7303e09 100644 --- a/code/_onclick/hud/pai.dm +++ b/code/_onclick/hud/pai.dm @@ -122,8 +122,7 @@ if(!..()) return var/mob/living/silicon/pai/pAI = usr - message_admins(pAI.loc) - if(pAI) + if(get(pAI, /obj/item/pda)) pAI.cmd_send_pdamesg(usr) else pAI.cmd_mc_send_pdamesg(usr) diff --git a/code/modules/modular_computers/file_system/programs/ntpda_msg.dm b/code/modules/modular_computers/file_system/programs/ntpda_msg.dm index 3fa1853d5b86..d4d56762226b 100644 --- a/code/modules/modular_computers/file_system/programs/ntpda_msg.dm +++ b/code/modules/modular_computers/file_system/programs/ntpda_msg.dm @@ -471,9 +471,11 @@ GLOBAL_LIST_EMPTY(NTPDAMessages) var/list/plist = list() var/list/namecounts = list() var/list/data = list() + message_admins("cmd_mc_send_pdamesg called") if(aiPDA.toff) to_chat(user, "Turn on your receiver in order to send messages.") return + message_admins("transceiver checked") data = ui_data(user) for(var/obj/item/modular_computer/P in data["pdas"]) if(P == src) @@ -482,7 +484,11 @@ GLOBAL_LIST_EMPTY(NTPDAMessages) continue plist[avoid_assoc_duplicate_keys(data["username"], namecounts)] = P + message_admins("for loop completed") + + //Something is wrong with this part, isn't giving the input var/c = input(user, "Please select a recipient") as null|anything in sortList(plist) + message_admins("input completed") if(!c) return @@ -493,4 +499,4 @@ GLOBAL_LIST_EMPTY(NTPDAMessages) return to_chat(user, "Success, cmd_mc_send_pdamesg ran") - to_chat(user, plist[c]) + to_chat(user, selected) From 237ffa51cff444f1053f124f6496d649ce566a9f Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Sun, 6 Oct 2024 01:25:17 +0100 Subject: [PATCH 13/40] TGUI start --- code/_onclick/hud/pai.dm | 7 +- code/modules/mob/living/silicon/pai/pai.dm | 2 +- .../mob/living/silicon/pai/software.dm | 212 ++++++++++-------- .../file_system/programs/ntpda_msg.dm | 35 --- .../packages/tgui/interfaces/PaiInterface.tsx | 48 ++++ 5 files changed, 169 insertions(+), 135 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/PaiInterface.tsx diff --git a/code/_onclick/hud/pai.dm b/code/_onclick/hud/pai.dm index 7159c7303e09..0d47892594e8 100644 --- a/code/_onclick/hud/pai.dm +++ b/code/_onclick/hud/pai.dm @@ -21,7 +21,7 @@ if(!..()) return var/mob/living/silicon/pai/pAI = usr - pAI.paiInterface() + pAI.ui_interact(usr) /atom/movable/screen/pai/shell name = "Toggle Holoform" @@ -122,10 +122,7 @@ if(!..()) return var/mob/living/silicon/pai/pAI = usr - if(get(pAI, /obj/item/pda)) - pAI.cmd_send_pdamesg(usr) - else - pAI.cmd_mc_send_pdamesg(usr) + pAI.cmd_send_pdamesg(usr) /atom/movable/screen/pai/pda_msg_show name = "PDA - Show Message Log" diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index e99985c7b18b..3b5de2e9f68a 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -219,7 +219,7 @@ /datum/action/innate/pai/software/Trigger() ..() - P.paiInterface() + P.ui_interact(usr) /datum/action/innate/pai/shell name = "Toggle Holoform" diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 77739a90a570..f8371726b4e6 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -32,101 +32,125 @@ "universal translator" = 35 ) -/mob/living/silicon/pai/proc/paiInterface() - var/dat = "" - var/left_part = "" - var/right_part = softwareMenu() - set_machine(src) - - if(temp) - left_part = temp - else if(stat == DEAD) // Show some flavor text if the pAI is dead - left_part = "ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ" - right_part = "
Program index hash not found
" - - else - switch(screen) // Determine which interface to show here - if("main") - left_part = "" - if("directives") - left_part = directives() - if("pdamessage") - left_part = pdamessage() - if("buy") - left_part = downloadSoftware() - if("manifest") - left_part = softwareManifest() - if("medicalrecord") - left_part = softwareMedicalRecord() - if("securityrecord") - left_part = softwareSecurityRecord() - if("encryptionkeys") - left_part = softwareEncryptionKeys() - if("translator") - left_part = softwareTranslator() - if("atmosensor") - left_part = softwareAtmo() - if("securityhud") - left_part = facialRecognition() - if("medicalhud") - left_part = medicalAnalysis() - if("doorjack") - left_part = softwareDoor() - if("camerajack") - left_part = softwareCamera() - if("signaller") - left_part = softwareSignal() - if("loudness") - left_part = softwareLoudness() - if("hostscan") - left_part = softwareHostScan() - - - //usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc - - - // Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality - dat = {" - - - - - - - -
- pAI OS -
-
-
[left_part]
-
[right_part]
-
- - "} //" - src << browse(dat, "window=pai;size=640x480;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1") - onclose(src, "pai") - temp = null +/mob/living/silicon/pai/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + message_admins("new ui created") + ui = new(user, src, "PaiInterface", "pAI Software Interface") + ui.open() + ui.set_autoupdate(TRUE) + +/mob/living/silicon/pai/ui_data(mob/user) + var/list/data = list() + data["section_title"] = "pAI interface" + data["modules"] = list() + return data + +/mob/living/silicon/pai/ui_act(action, params) + if(..()) + return + switch(action) + if("PaiInterface") + var/newvar = params["var"] + . = TRUE + update_appearance(UPDATE_ICON) +/mob/living/silicon/pai/proc/paiInterface() + // + //var/dat = "" + //var/left_part = "" + //var/right_part = softwareMenu() + //set_machine(src) +// + //if(temp) + // left_part = temp + //else if(stat == DEAD) // Show some flavor text if the pAI is dead + // left_part = "ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ" + // right_part = "
Program index hash not found
" +// + //else + // switch(screen) // Determine which interface to show here + // if("main") + // left_part = "" + // if("directives") + // left_part = directives() + // if("pdamessage") + // left_part = pdamessage() + // if("buy") + // left_part = downloadSoftware() + // if("manifest") + // left_part = softwareManifest() + // if("medicalrecord") + // left_part = softwareMedicalRecord() + // if("securityrecord") + // left_part = softwareSecurityRecord() + // if("encryptionkeys") + // left_part = softwareEncryptionKeys() + // if("translator") + // left_part = softwareTranslator() + // if("atmosensor") + // left_part = softwareAtmo() + // if("securityhud") + // left_part = facialRecognition() + // if("medicalhud") + // left_part = medicalAnalysis() + // if("doorjack") + // left_part = softwareDoor() + // if("camerajack") + // left_part = softwareCamera() + // if("signaller") + // left_part = softwareSignal() + // if("loudness") + // left_part = softwareLoudness() + // if("hostscan") + // left_part = softwareHostScan() +// +// + ////usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc +// +// + // // Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality + //dat = {" + // + // + // + // + // + // + // + //
+ // pAI OS + //
+ //
+ //
[left_part]
+ //
[right_part]
+ //
+ // + // "} //" + //src << browse(dat, "window=pai;size=640x480;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1") + //onclose(src, "pai") + //temp = null +// /mob/living/silicon/pai/Topic(href, href_list) if(..()) return diff --git a/code/modules/modular_computers/file_system/programs/ntpda_msg.dm b/code/modules/modular_computers/file_system/programs/ntpda_msg.dm index d4d56762226b..5dd70dea1827 100644 --- a/code/modules/modular_computers/file_system/programs/ntpda_msg.dm +++ b/code/modules/modular_computers/file_system/programs/ntpda_msg.dm @@ -465,38 +465,3 @@ GLOBAL_LIST_EMPTY(NTPDAMessages) data["all_messages"] = list() return data - -//pAI verb and proc for sending PDA messages. -/mob/living/silicon/pai/proc/cmd_mc_send_pdamesg(mob/user) - var/list/plist = list() - var/list/namecounts = list() - var/list/data = list() - message_admins("cmd_mc_send_pdamesg called") - if(aiPDA.toff) - to_chat(user, "Turn on your receiver in order to send messages.") - return - message_admins("transceiver checked") - data = ui_data(user) - for(var/obj/item/modular_computer/P in data["pdas"]) - if(P == src) - continue - else if(P == aiPDA) - continue - plist[avoid_assoc_duplicate_keys(data["username"], namecounts)] = P - - message_admins("for loop completed") - - //Something is wrong with this part, isn't giving the input - var/c = input(user, "Please select a recipient") as null|anything in sortList(plist) - message_admins("input completed") - - if(!c) - return - - var/selected = plist[c] - - if(incapacitated()) - return - - to_chat(user, "Success, cmd_mc_send_pdamesg ran") - to_chat(user, selected) diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx new file mode 100644 index 000000000000..d0ae775d11fc --- /dev/null +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -0,0 +1,48 @@ +import { useBackend, useLocalState } from '../backend'; +import { Box, Button, Section, Flex, Tabs } from '../components'; +import { Window } from '../layouts'; + +type Modules = { + +} + +type Data = { + +} + +type Category = { + name: string; + +} + +export const PaiInterface = (props, context) => { + const { act, data } = useBackend(context); + const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", 0); + const winWidth = Math.min(450, window.screen.availWidth * 0.5); + const winHeight = Math.min(500, window.screen.availHeight * 0.8); + return ( + + + + +
+ Test +
+
+ +
+ + + Directives + + + Download software + + +
+
+
+
+
+ ); +}; From c30653c381bf2bc9346c2baf688d40b5902af297 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:45:38 +0100 Subject: [PATCH 14/40] .map() --- .../mob/living/silicon/pai/software.dm | 1 + .../packages/tgui/interfaces/PaiInterface.tsx | 20 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index f8371726b4e6..76ae7cef9ee4 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -44,6 +44,7 @@ var/list/data = list() data["section_title"] = "pAI interface" data["modules"] = list() + data["modules_tabs"] = list() return data /mob/living/silicon/pai/ui_act(action, params) diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index d0ae775d11fc..7aa4d8c0fc2d 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -1,13 +1,14 @@ +import { capitalize } from 'common/string'; import { useBackend, useLocalState } from '../backend'; import { Box, Button, Section, Flex, Tabs } from '../components'; import { Window } from '../layouts'; -type Modules = { - +type Module = { + module_name: string; } type Data = { - + modules_tabs: Module[]; } type Category = { @@ -16,8 +17,9 @@ type Category = { } export const PaiInterface = (props, context) => { - const { act, data } = useBackend(context); - const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", 0); + const { act, data } = useBackend(context); + const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", null); + const { modules_tabs = [] } = data; const winWidth = Math.min(450, window.screen.availWidth * 0.5); const winHeight = Math.min(500, window.screen.availHeight * 0.8); return ( @@ -38,6 +40,14 @@ export const PaiInterface = (props, context) => { Download software + {modules_tabs.map(module => ( + setMainTab(module)}> + {capitalize(module.module_name)} + + ))} From 85b6fbbd77f55d2b99dfbd894be1bfc69f52f81b Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Mon, 7 Oct 2024 18:10:46 +0100 Subject: [PATCH 15/40] Update PaiInterface.tsx --- tgui/packages/tgui/interfaces/PaiInterface.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index d0ae775d11fc..a36f06579718 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -21,7 +21,7 @@ export const PaiInterface = (props, context) => { const winWidth = Math.min(450, window.screen.availWidth * 0.5); const winHeight = Math.min(500, window.screen.availHeight * 0.8); return ( - + @@ -38,6 +38,7 @@ export const PaiInterface = (props, context) => { Download software + From bad89bf3938c4c661d7df7473310d7496a54b837 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Thu, 10 Oct 2024 01:10:36 +0100 Subject: [PATCH 16/40] Attempted debugging --- code/modules/mob/living/silicon/pai/software.dm | 6 +++++- tgui/packages/tgui/interfaces/PaiInterface.tsx | 15 +++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 76ae7cef9ee4..ba7fa6b041fc 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -44,7 +44,11 @@ var/list/data = list() data["section_title"] = "pAI interface" data["modules"] = list() - data["modules_tabs"] = list() + data["modules_tabs"] = "Directives" + data["modules_tabs"] = "Download software" + message_admins(data) + message_admins(data["modules"]) + message_admins(data["modules_tabs"]) return data /mob/living/silicon/pai/ui_act(action, params) diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index 572893a2017a..f1bdcd4a6ff9 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -5,6 +5,9 @@ import { Window } from '../layouts'; type Module = { module_name: string; + title: string; + text: string; + module: Module[]; } type Data = { @@ -20,26 +23,18 @@ export const PaiInterface = (props, context) => { const { act, data } = useBackend(context); const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", null); const { modules_tabs = [] } = data; - const winWidth = Math.min(450, window.screen.availWidth * 0.5); - const winHeight = Math.min(500, window.screen.availHeight * 0.8); return ( -
+
Test
-
+
- - Directives - - - Download software - {modules_tabs.map(module => ( Date: Sat, 12 Oct 2024 16:15:04 +0100 Subject: [PATCH 17/40] Not causing errors now --- .../mob/living/silicon/pai/software.dm | 7 ++---- .../packages/tgui/interfaces/PaiInterface.tsx | 23 ++++++++++++++----- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index ba7fa6b041fc..0db88fdcd631 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -44,11 +44,8 @@ var/list/data = list() data["section_title"] = "pAI interface" data["modules"] = list() - data["modules_tabs"] = "Directives" - data["modules_tabs"] = "Download software" - message_admins(data) - message_admins(data["modules"]) - message_admins(data["modules_tabs"]) + data["modules_tabs"] = list(list("module_name" = "Directives", "title"="Directives"), + list("module_name" = "Download additional software", "title"="CentCom pAI Module Subversion Network")) return data /mob/living/silicon/pai/ui_act(action, params) diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index f1bdcd4a6ff9..b5ac87074cdd 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -7,7 +7,6 @@ type Module = { module_name: string; title: string; text: string; - module: Module[]; } type Data = { @@ -21,16 +20,14 @@ type Category = { export const PaiInterface = (props, context) => { const { act, data } = useBackend(context); - const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", null); const { modules_tabs = [] } = data; + const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", null); return ( - + -
- Test -
+
@@ -51,3 +48,17 @@ export const PaiInterface = (props, context) => { ); }; + +const PaiBox = (props, context) => { + const { data } = useBackend(context); + const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", null); + if(selectedMainTab!==null) { + return ( + <> +
+ Test +
+ + ); + } +}; From 31014b915cf2ba9099739e4cc932b83d4e8f20f2 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Sun, 13 Oct 2024 09:41:28 +0100 Subject: [PATCH 18/40] Directives --- .../mob/living/silicon/pai/software.dm | 3 ++ .../packages/tgui/interfaces/PaiInterface.tsx | 28 +++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 0db88fdcd631..40e7101f1d2d 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -46,6 +46,9 @@ data["modules"] = list() data["modules_tabs"] = list(list("module_name" = "Directives", "title"="Directives"), list("module_name" = "Download additional software", "title"="CentCom pAI Module Subversion Network")) + data["laws_zeroth"] = laws.zeroth + data["laws"] = laws.supplied + message_admins(data["laws_zeroth"]) return data /mob/living/silicon/pai/ui_act(action, params) diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index b5ac87074cdd..375f12e55d70 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -11,11 +11,8 @@ type Module = { type Data = { modules_tabs: Module[]; -} - -type Category = { - name: string; - + prime: string; + laws: Data[]; } export const PaiInterface = (props, context) => { @@ -52,13 +49,20 @@ export const PaiInterface = (props, context) => { const PaiBox = (props, context) => { const { data } = useBackend(context); const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", null); - if(selectedMainTab!==null) { - return ( - <> -
- Test + const { prime } = data; + const { laws } = data; + if(selectedMainTab===null) { + return; + } + switch(selectedMainTab.module_name) { + case "Directives": + return ( +
+ Prime directive: + {prime} + Supplemental Directives: + {laws.map(data => data)}
- - ); + ); } }; From d330818c75802fd69189ac2bf812ceea541317f4 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Sun, 13 Oct 2024 23:21:38 +0100 Subject: [PATCH 19/40] That's one page (somewhat) done --- .../mob/living/silicon/pai/software.dm | 193 +++++++++--------- .../packages/tgui/interfaces/PaiInterface.tsx | 52 ++++- 2 files changed, 139 insertions(+), 106 deletions(-) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index e5f7c8828fb1..5ee02aea3453 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -42,13 +42,13 @@ /mob/living/silicon/pai/ui_data(mob/user) var/list/data = list() - data["section_title"] = "pAI interface" data["modules"] = list() data["modules_tabs"] = list(list("module_name" = "Directives", "title"="Directives"), list("module_name" = "Download additional software", "title"="CentCom pAI Module Subversion Network")) data["laws_zeroth"] = laws.zeroth data["laws"] = laws.supplied - message_admins(data["laws_zeroth"]) + data["master"] = master + data["masterdna"] = master_dna return data /mob/living/silicon/pai/ui_act(action, params) @@ -56,106 +56,103 @@ return switch(action) if("PaiInterface") - var/newvar = params["var"] . = TRUE update_appearance(UPDATE_ICON) /mob/living/silicon/pai/proc/paiInterface() - // - //var/dat = "" - //var/left_part = "" - //var/right_part = softwareMenu() - //set_machine(src) -// - //if(temp) - // left_part = temp - //else if(stat == DEAD) // Show some flavor text if the pAI is dead - // left_part = "ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ" - // right_part = "
Program index hash not found
" -// - //else - // switch(screen) // Determine which interface to show here - // if("main") - // left_part = "" - // if("directives") - // left_part = directives() - // if("pdamessage") - // left_part = pdamessage() - // if("buy") - // left_part = downloadSoftware() - // if("manifest") - // left_part = softwareManifest() - // if("medicalrecord") - // left_part = softwareMedicalRecord() - // if("securityrecord") - // left_part = softwareSecurityRecord() - // if("encryptionkeys") - // left_part = softwareEncryptionKeys() - // if("translator") - // left_part = softwareTranslator() - // if("atmosensor") - // left_part = softwareAtmo() - // if("securityhud") - // left_part = facialRecognition() - // if("medicalhud") - // left_part = medicalAnalysis() - // if("doorjack") - // left_part = softwareDoor() - // if("camerajack") - // left_part = softwareCamera() - // if("signaller") - // left_part = softwareSignal() - // if("loudness") - // left_part = softwareLoudness() - // if("hostscan") - // left_part = softwareHostScan() -// -// - ////usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc -// -// - // // Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality - //dat = {" - // - // - // - // - // - // - // - //
- // pAI OS - //
- //
- //
[left_part]
- //
[right_part]
- //
- // - // "} //" - //src << browse(dat, "window=pai;size=640x480;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1") - //onclose(src, "pai") - //temp = null -// + + var/dat = "" + var/left_part = "" + var/right_part = softwareMenu() + set_machine(src) + + if(temp) + left_part = temp + else if(stat == DEAD) // Show some flavor text if the pAI is dead + left_part = "ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ" + right_part = "
Program index hash not found
" + + else + switch(screen) // Determine which interface to show here + if("main") + left_part = "" + if("directives") + left_part = directives() + if("buy") + left_part = downloadSoftware() + if("manifest") + left_part = softwareManifest() + if("medicalrecord") + left_part = softwareMedicalRecord() + if("securityrecord") + left_part = softwareSecurityRecord() + if("encryptionkeys") + left_part = softwareEncryptionKeys() + if("translator") + left_part = softwareTranslator() + if("atmosensor") + left_part = softwareAtmo() + if("securityhud") + left_part = facialRecognition() + if("medicalhud") + left_part = medicalAnalysis() + if("doorjack") + left_part = softwareDoor() + if("camerajack") + left_part = softwareCamera() + if("signaller") + left_part = softwareSignal() + if("loudness") + left_part = softwareLoudness() + if("hostscan") + left_part = softwareHostScan() + + + //usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc + + + // Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality + dat = {" + + + + + + + +
+ pAI OS +
+
+
[left_part]
+
[right_part]
+
+ + "} //" + src << browse(dat, "window=pai;size=640x480;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1") + onclose(src, "pai") + temp = null + /mob/living/silicon/pai/Topic(href, href_list) if(..()) return diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index 375f12e55d70..7c96270b660c 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -1,6 +1,6 @@ import { capitalize } from 'common/string'; import { useBackend, useLocalState } from '../backend'; -import { Box, Button, Section, Flex, Tabs } from '../components'; +import { Box, Button, Section, Flex, Tabs, Stack, BlockQuote } from '../components'; import { Window } from '../layouts'; type Module = { @@ -11,8 +11,10 @@ type Module = { type Data = { modules_tabs: Module[]; - prime: string; + laws_zeroth: string; laws: Data[]; + master: string; + masterdna: string; } export const PaiInterface = (props, context) => { @@ -49,8 +51,7 @@ export const PaiInterface = (props, context) => { const PaiBox = (props, context) => { const { data } = useBackend(context); const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", null); - const { prime } = data; - const { laws } = data; + const { laws_zeroth, laws, master, masterdna } = data; if(selectedMainTab===null) { return; } @@ -58,10 +59,45 @@ const PaiBox = (props, context) => { case "Directives": return (
- Prime directive: - {prime} - Supplemental Directives: - {laws.map(data => data)} + + + {!master && ( + + You are bound to no one. + )} + {!!master && ( + + Your master: {master} ({masterdna}) + + )} + + + + Prime directive: + {laws_zeroth} + + + Supplemental Directives: + {laws.map(data => data)} + + +
+ + Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of + comprehending the subtle nuances of human language. You may parse the "spirit" of a directive and follow its intent, + rather than tripping over pedantics and getting snared by technicalities. Above all, you are machine in name and build + only. In all other aspects, you may be seen as the ideal, unwavering human companion that you are. + + + Your prime directive comes before all others. Should a supplemental directive conflict with it, you are capable of + simply discarding this inconsistency, ignoring the conflicting supplemental directive and continuing to fulfill your + prime directive to the best of your ability. + +
+
+
); } From c9f6857624de8a811e683f4c0556e76903eff88e Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:25:14 +0100 Subject: [PATCH 20/40] Now for software --- .../mob/living/silicon/pai/software.dm | 10 ++++-- .../packages/tgui/interfaces/PaiInterface.tsx | 31 +++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 5ee02aea3453..a71548b19b0e 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -43,20 +43,26 @@ /mob/living/silicon/pai/ui_data(mob/user) var/list/data = list() data["modules"] = list() + data["modules_list"] = available_software data["modules_tabs"] = list(list("module_name" = "Directives", "title"="Directives"), list("module_name" = "Download additional software", "title"="CentCom pAI Module Subversion Network")) data["laws_zeroth"] = laws.zeroth data["laws"] = laws.supplied data["master"] = master data["masterdna"] = master_dna + data["ram"] = ram return data /mob/living/silicon/pai/ui_act(action, params) if(..()) return switch(action) - if("PaiInterface") - . = TRUE + if("getdna") + if(iscarbon(card.loc)) + CheckDNA(card.loc, src) //you should only be able to check when directly in hand, muh immersions? + else + to_chat(src, "You are not being carried by anyone!") + return 0 // FALSE ? If you return here you won't call paiinterface() below update_appearance(UPDATE_ICON) /mob/living/silicon/pai/proc/paiInterface() diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index 7c96270b660c..ab703b57ab54 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -10,11 +10,14 @@ type Module = { } type Data = { + modules: Data[]; + modules_list: Data[]; modules_tabs: Module[]; laws_zeroth: string; laws: Data[]; master: string; masterdna: string; + ram: number; } export const PaiInterface = (props, context) => { @@ -49,8 +52,9 @@ export const PaiInterface = (props, context) => { }; const PaiBox = (props, context) => { - const { data } = useBackend(context); + const { act, data } = useBackend(context); const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", null); + const { modules, ram, modules_list } = data; const { laws_zeroth, laws, master, masterdna } = data; if(selectedMainTab===null) { return; @@ -70,7 +74,8 @@ const PaiBox = (props, context) => { Your master: {master} ({masterdna}) )} - @@ -100,5 +105,27 @@ const PaiBox = (props, context) => {
); + case "Download additional software": + return ( +
+ + + Downloaded modules: {modules.map(data => data)} + Remaining available memory: {ram} + + {modules_list.map(module => ( + + {module} + + ))} + +
+ ); + case "Remote signaller": + return ( +
+ +
+ ); } }; From 5c1f9d82badbf9e32266ffa668715ab73b32ef97 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Mon, 14 Oct 2024 23:37:08 +0100 Subject: [PATCH 21/40] All modules converted --- code/modules/mob/living/silicon/pai/pai.dm | 2 +- .../mob/living/silicon/pai/software.dm | 1175 +++++++++-------- .../packages/tgui/interfaces/PaiInterface.tsx | 20 +- 3 files changed, 602 insertions(+), 595 deletions(-) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index d1057bb0d251..1170d8a86a6f 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -159,7 +159,7 @@ hackdoor = null return if(screen == "doorjack" && subscreen == 0) // Update our view, if appropriate - paiInterface() + //paiInterface() if(hackprogress >= 100) hackprogress = 0 var/obj/machinery/door/D = cable.machine diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index a71548b19b0e..c4b06898276e 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -11,25 +11,25 @@ //radiation eyes //chem goggs //mesons - "crew manifest" = 5, - "digital messenger" = 5, - "atmosphere sensor" = 5, - "photography module" = 5, - "remote signaller" = 10, - "medical records" = 10, - "security records" = 10, - "camera zoom" = 10, - "host scan" = 10, + list("module_name" = "crew manifest", "cost" = 5), + list("module_name" = "digital messenger", "cost" = 5), + list("module_name" = "atmosphere sensor", "cost" = 5), + list("module_name" = "photography module", "cost" = 5), + list("module_name" = "remote signaller", "cost" = 10), + list("module_name" = "medical records", "cost" = 10), + list("module_name" = "security records", "cost" = 10), + list("module_name" = "camera zoom", "cost" = 10), + list("module_name" = "host scan", "cost" = 10), //"camera jack" = 10, //"heartbeat sensor" = 10, //"projection array" = 15, - "medical HUD" = 20, - "security HUD" = 20, - "loudness booster" = 20, - "newscaster" = 20, - "door jack" = 25, - "encryption keys" = 25, - "universal translator" = 35 + list("module_name" = "medical HUD", "cost" = 20), + list("module_name" = "security HUD", "cost" = 20), + list("module_name" = "loudness booster", "cost" = 20), + list("module_name" = "newscaster", "cost" = 20), + list("module_name" = "door jack", "cost" = 25), + list("module_name" = "encryption keys", "cost" = 25), + list("module_name" = "universal translator", "cost" = 35) ) /mob/living/silicon/pai/ui_interact(mob/user, datum/tgui/ui) @@ -65,361 +65,361 @@ return 0 // FALSE ? If you return here you won't call paiinterface() below update_appearance(UPDATE_ICON) -/mob/living/silicon/pai/proc/paiInterface() - - var/dat = "" - var/left_part = "" - var/right_part = softwareMenu() - set_machine(src) - - if(temp) - left_part = temp - else if(stat == DEAD) // Show some flavor text if the pAI is dead - left_part = "ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ" - right_part = "
Program index hash not found
" - - else - switch(screen) // Determine which interface to show here - if("main") - left_part = "" - if("directives") - left_part = directives() - if("buy") - left_part = downloadSoftware() - if("manifest") - left_part = softwareManifest() - if("medicalrecord") - left_part = softwareMedicalRecord() - if("securityrecord") - left_part = softwareSecurityRecord() - if("encryptionkeys") - left_part = softwareEncryptionKeys() - if("translator") - left_part = softwareTranslator() - if("atmosensor") - left_part = softwareAtmo() - if("securityhud") - left_part = facialRecognition() - if("medicalhud") - left_part = medicalAnalysis() - if("doorjack") - left_part = softwareDoor() - if("camerajack") - left_part = softwareCamera() - if("signaller") - left_part = softwareSignal() - if("loudness") - left_part = softwareLoudness() - if("hostscan") - left_part = softwareHostScan() - - - //usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc - - - // Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality - dat = {" - - - - - - - -
- pAI OS -
-
-
[left_part]
-
[right_part]
-
- - "} //" - src << browse(dat, "window=pai;size=640x480;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1") - onclose(src, "pai") - temp = null - -/mob/living/silicon/pai/Topic(href, href_list) - if(..()) - return - var/soft = href_list["software"] - var/sub = href_list["sub"] - if(soft) - screen = soft - if(sub) - subscreen = text2num(sub) - switch(soft) - if("buy") // Purchasing new software - if(subscreen == 1) - var/target = href_list["buy"] - if(available_software.Find(target) && !software.Find(target)) - var/cost = available_software[target] - if(ram >= cost) - software.Add(target) - ram -= cost - var/datum/hud/pai/pAIhud = hud_used - pAIhud?.update_software_buttons() - else - temp = "Insufficient RAM available." - else - temp = "Trunk \"[target]\" not found." - - - if("radio") // Configuring onboard radio - radio.attack_self(src) - - if("image") // Set pAI card display face - var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What") - var/pID = 1 - - switch(newImage) - if("Happy") - pID = 1 - if("Cat") - pID = 2 - if("Extremely Happy") - pID = 3 - if("Face") - pID = 4 - if("Laugh") - pID = 5 - if("Off") - pID = 6 - if("Sad") - pID = 7 - if("Angry") - pID = 8 - if("What") - pID = 9 - if("Null") - pID = 10 - card.setEmotion(pID) - - if("news") - newscaster.ui_interact(src) - - if("camzoom") - aicamera.adjust_zoom(usr) - - if("signaller") - if(href_list["send"]) - signaler.signal() - audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*") - playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) - - if(href_list["freq"]) - var/new_frequency = (signaler.frequency + text2num(href_list["freq"])) - if(new_frequency < MIN_FREE_FREQ || new_frequency > MAX_FREE_FREQ) - new_frequency = sanitize_frequency(new_frequency) - signaler.set_frequency(new_frequency) - - if(href_list["code"]) - signaler.code += text2num(href_list["code"]) - signaler.code = round(signaler.code) - signaler.code = min(100, signaler.code) - signaler.code = max(1, signaler.code) - - if("directive") - if(href_list["getdna"]) - if(iscarbon(card.loc)) - CheckDNA(card.loc, src) //you should only be able to check when directly in hand, muh immersions? - else - to_chat(src, "You are not being carried by anyone!") - return 0 // FALSE ? If you return here you won't call paiinterface() below - - if("medicalrecord") // Accessing medical records - if(subscreen == 1) - medicalActive1 = find_record("id", href_list["med_rec"], GLOB.data_core.general) - if(medicalActive1) - medicalActive2 = find_record("id", href_list["med_rec"], GLOB.data_core.medical) - if(!medicalActive2) - medicalActive1 = null - temp = "Unable to locate requested security record. Record may have been deleted, or never have existed." - - if("securityrecord") - if(subscreen == 1) - securityActive1 = find_record("id", href_list["sec_rec"], GLOB.data_core.general) - if(securityActive1) - securityActive2 = find_record("id", href_list["sec_rec"], GLOB.data_core.security) - if(!securityActive2) - securityActive1 = null - temp = "Unable to locate requested security record. Record may have been deleted, or never have existed." - - if("securityhud") - if(href_list["toggle"]) - secHUD = !secHUD - if(secHUD) - var/datum/atom_hud/sec = GLOB.huds[sec_hud] - sec.show_to(src) - else - var/datum/atom_hud/sec = GLOB.huds[sec_hud] - sec.hide_from(src) - - if("medicalhud") - if(href_list["toggle"]) - medHUD = !medHUD - if(medHUD) - var/datum/atom_hud/med = GLOB.huds[med_hud] - med.show_to(src) - else - var/datum/atom_hud/med = GLOB.huds[med_hud] - med.hide_from(src) - - if("hostscan") - if(href_list["toggle"]) - var/mob/living/silicon/pai/pAI = usr - pAI.hostscan.attack_self(usr) - - if("encryptionkeys") - if(href_list["toggle"]) - encryptmod = TRUE - - if("translator") - if(href_list["toggle"]) //This is permanent. - grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE) - - if("doorjack") - if(href_list["jack"]) - if(cable && cable.machine) - hackdoor = cable.machine - hackloop() - if(href_list["cancel"]) - hackdoor = null - if(href_list["cable"]) - var/turf/T = get_turf(loc) - cable = new /obj/item/pai_cable(T) - T.visible_message(span_warning("A port on [src] opens to reveal [cable], which promptly falls to the floor."), span_italics("You hear the soft click of something light and hard falling to the ground.")) - - if("loudness") - if(subscreen == 1) // Open Instrument - internal_instrument.interact(src) - - paiInterface() - -// MENUS - -/mob/living/silicon/pai/proc/softwareMenu() // Populate the right menu - var/dat = "" - - dat += "Refresh
" - // Built-in - dat += "Directives
" - dat += "Radio Configuration
" - dat += "Screen Display
" - //dat += "Text Messaging
" - dat += "
" - - // Basic - dat += "Basic
" - for(var/s in software) - if(s == "crew manifest") - dat += "Crew Manifest
" - if(s == "host scan") - dat += "Host Health Scan" - if(s == "medical records") - dat += "Medical Records
" - if(s == "security records") - dat += "Security Records
" - if(s == "camera") - dat += "Camera Jack
" - if(s == "remote signaller") - dat += "Remote Signaller
" - if(s == "loudness booster") - dat += "Loudness Booster
" - dat += "
" - - // Advanced - dat += "Advanced
" - for(var/s in software) - if(s == "camera zoom") - dat += "Adjust Camera Zoom
" - if(s == "atmosphere sensor") - dat += "Atmospheric Sensor
" - if(s == "heartbeat sensor") - dat += "Heartbeat Sensor
" - if(s == "security HUD") - dat += "Facial Recognition Suite[(secHUD) ? " On" : " Off"]
" - if(s == "medical HUD") - dat += "Medical Analysis Suite[(medHUD) ? " On" : " Off"]
" - if(s == "encryption keys") - dat += "Channel Encryption Firmware[(encryptmod) ? " On" : " Off"]
" - if(s == "universal translator") - var/datum/language_holder/H = get_language_holder() - dat += "Universal Translator[H.omnitongue ? " On" : " Off"]
" - if(s == "projection array") - dat += "Projection Array
" - if(s == "camera jack") - dat += "Camera Jack
" - if(s == "door jack") - dat += "Door Jack
" - dat += "
" - dat += "
" - dat += "Download additional software" - return dat - - - -/mob/living/silicon/pai/proc/downloadSoftware() - var/dat = "" - - dat += "

CentCom pAI Module Subversion Network


" - dat += "
Remaining Available Memory: [ram]

" - dat += "

Trunks available for checkout
" - - for(var/s in available_software) - if(!software.Find(s)) - var/cost = available_software[s] - var/displayName = uppertext(s) - dat += "[displayName] ([cost])
" - else - var/displayName = lowertext(s) - dat += "[displayName] (Download Complete)
" - dat += "

" - return dat - - -/mob/living/silicon/pai/proc/directives() - var/dat = "" - - dat += "[(master) ? "Your master: [master] ([master_dna])" : "You are bound to no one."]" - dat += "

" - dat += "Request carrier DNA sample
" - dat += "

Directives


" - dat += "Prime Directive
" - dat += "     [laws.zeroth]
" - dat += "Supplemental Directives
" - for(var/slaws in laws.supplied) - dat += "     [slaws]
" - dat += "
" - dat += {"

Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of - comprehending the subtle nuances of human language. You may parse the \"spirit\" of a directive and follow its intent, - rather than tripping over pedantics and getting snared by technicalities. Above all, you are machine in name and build - only. In all other aspects, you may be seen as the ideal, unwavering human companion that you are.



- Your prime directive comes before all others. Should a supplemental directive conflict with it, you are capable of - simply discarding this inconsistency, ignoring the conflicting supplemental directive and continuing to fulfill your - prime directive to the best of your ability.



- - "} - return dat +///mob/living/silicon/pai/proc/paiInterface() +// +// var/dat = "" +// var/left_part = "" +// var/right_part = softwareMenu() +// set_machine(src) +// +// if(temp) +// left_part = temp +// else if(stat == DEAD) // Show some flavor text if the pAI is dead +// left_part = "ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ" +// right_part = "
Program index hash not found
" +// +// else +// switch(screen) // Determine which interface to show here +// if("main") +// left_part = "" +// if("directives") +// left_part = directives() +// if("buy") +// left_part = downloadSoftware() +// if("manifest") +// left_part = softwareManifest() +// if("medicalrecord") +// left_part = softwareMedicalRecord() +// if("securityrecord") +// left_part = softwareSecurityRecord() +// if("encryptionkeys") +// left_part = softwareEncryptionKeys() +// if("translator") +// left_part = softwareTranslator() +// if("atmosensor") +// left_part = softwareAtmo() +// if("securityhud") +// left_part = facialRecognition() +// if("medicalhud") +// left_part = medicalAnalysis() +// if("doorjack") +// left_part = softwareDoor() +// if("camerajack") +// left_part = softwareCamera() +// if("signaller") +// left_part = softwareSignal() +// if("loudness") +// left_part = softwareLoudness() +// if("hostscan") +// left_part = softwareHostScan() +// +// +// //usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc +// +// +// // Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality +// dat = {" +// +// +// +// +// +// +// +//
+// pAI OS +//
+//
+//
[left_part]
+//
[right_part]
+//
+// +// "} //" +// src << browse(dat, "window=pai;size=640x480;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1") +// onclose(src, "pai") +// temp = null +// +///mob/living/silicon/pai/Topic(href, href_list) +// if(..()) +// return +// var/soft = href_list["software"] +// var/sub = href_list["sub"] +// if(soft) +// screen = soft +// if(sub) +// subscreen = text2num(sub) +// switch(soft) +// if("buy") // Purchasing new software +// if(subscreen == 1) +// var/target = href_list["buy"] +// if(available_software.Find(target) && !software.Find(target)) +// var/cost = available_software[target] +// if(ram >= cost) +// software.Add(target) +// ram -= cost +// var/datum/hud/pai/pAIhud = hud_used +// pAIhud?.update_software_buttons() +// else +// temp = "Insufficient RAM available." +// else +// temp = "Trunk \"[target]\" not found." +// +// +// if("radio") // Configuring onboard radio +// radio.attack_self(src) +// +// if("image") // Set pAI card display face +// var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What") +// var/pID = 1 +// +// switch(newImage) +// if("Happy") +// pID = 1 +// if("Cat") +// pID = 2 +// if("Extremely Happy") +// pID = 3 +// if("Face") +// pID = 4 +// if("Laugh") +// pID = 5 +// if("Off") +// pID = 6 +// if("Sad") +// pID = 7 +// if("Angry") +// pID = 8 +// if("What") +// pID = 9 +// if("Null") +// pID = 10 +// card.setEmotion(pID) +// +// if("news") +// newscaster.ui_interact(src) +// +// if("camzoom") +// aicamera.adjust_zoom(usr) +// +// if("signaller") +// if(href_list["send"]) +// signaler.signal() +// audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*") +// playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE) +// +// if(href_list["freq"]) +// var/new_frequency = (signaler.frequency + text2num(href_list["freq"])) +// if(new_frequency < MIN_FREE_FREQ || new_frequency > MAX_FREE_FREQ) +// new_frequency = sanitize_frequency(new_frequency) +// signaler.set_frequency(new_frequency) +// +// if(href_list["code"]) +// signaler.code += text2num(href_list["code"]) +// signaler.code = round(signaler.code) +// signaler.code = min(100, signaler.code) +// signaler.code = max(1, signaler.code) +// +// if("directive") +// if(href_list["getdna"]) +// if(iscarbon(card.loc)) +// CheckDNA(card.loc, src) //you should only be able to check when directly in hand, muh immersions? +// else +// to_chat(src, "You are not being carried by anyone!") +// return 0 // FALSE ? If you return here you won't call paiinterface() below +// +// if("medicalrecord") // Accessing medical records +// if(subscreen == 1) +// medicalActive1 = find_record("id", href_list["med_rec"], GLOB.data_core.general) +// if(medicalActive1) +// medicalActive2 = find_record("id", href_list["med_rec"], GLOB.data_core.medical) +// if(!medicalActive2) +// medicalActive1 = null +// temp = "Unable to locate requested security record. Record may have been deleted, or never have existed." +// +// if("securityrecord") +// if(subscreen == 1) +// securityActive1 = find_record("id", href_list["sec_rec"], GLOB.data_core.general) +// if(securityActive1) +// securityActive2 = find_record("id", href_list["sec_rec"], GLOB.data_core.security) +// if(!securityActive2) +// securityActive1 = null +// temp = "Unable to locate requested security record. Record may have been deleted, or never have existed." +// +// if("securityhud") +// if(href_list["toggle"]) +// secHUD = !secHUD +// if(secHUD) +// var/datum/atom_hud/sec = GLOB.huds[sec_hud] +// sec.show_to(src) +// else +// var/datum/atom_hud/sec = GLOB.huds[sec_hud] +// sec.hide_from(src) +// +// if("medicalhud") +// if(href_list["toggle"]) +// medHUD = !medHUD +// if(medHUD) +// var/datum/atom_hud/med = GLOB.huds[med_hud] +// med.show_to(src) +// else +// var/datum/atom_hud/med = GLOB.huds[med_hud] +// med.hide_from(src) +// +// if("hostscan") +// if(href_list["toggle"]) +// var/mob/living/silicon/pai/pAI = usr +// pAI.hostscan.attack_self(usr) +// +// if("encryptionkeys") +// if(href_list["toggle"]) +// encryptmod = TRUE +// +// if("translator") +// if(href_list["toggle"]) //This is permanent. +// grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE) +// +// if("doorjack") +// if(href_list["jack"]) +// if(cable && cable.machine) +// hackdoor = cable.machine +// hackloop() +// if(href_list["cancel"]) +// hackdoor = null +// if(href_list["cable"]) +// var/turf/T = get_turf(loc) +// cable = new /obj/item/pai_cable(T) +// T.visible_message(span_warning("A port on [src] opens to reveal [cable], which promptly falls to the floor."), span_italics("You hear the soft click of something light and hard falling to the ground.")) +// +// if("loudness") +// if(subscreen == 1) // Open Instrument +// internal_instrument.interact(src) +// +// paiInterface() +// +//// MENUS +// +///mob/living/silicon/pai/proc/softwareMenu() // Populate the right menu +// var/dat = "" +// +// dat += "Refresh
" +// // Built-in +// dat += "Directives
" +// dat += "Radio Configuration
" +// dat += "Screen Display
" +// //dat += "Text Messaging
" +// dat += "
" +// +// // Basic +// dat += "Basic
" +// for(var/s in software) +// if(s == "crew manifest") +// dat += "Crew Manifest
" +// if(s == "host scan") +// dat += "Host Health Scan" +// if(s == "medical records") +// dat += "Medical Records
" +// if(s == "security records") +// dat += "Security Records
" +// if(s == "camera") +// dat += "Camera Jack
" +// if(s == "remote signaller") +// dat += "Remote Signaller
" +// if(s == "loudness booster") +// dat += "Loudness Booster
" +// dat += "
" +// +// // Advanced +// dat += "Advanced
" +// for(var/s in software) +// if(s == "camera zoom") +// dat += "Adjust Camera Zoom
" +// if(s == "atmosphere sensor") +// dat += "Atmospheric Sensor
" +// if(s == "heartbeat sensor") +// dat += "Heartbeat Sensor
" +// if(s == "security HUD") +// dat += "Facial Recognition Suite[(secHUD) ? " On" : " Off"]
" +// if(s == "medical HUD") +// dat += "Medical Analysis Suite[(medHUD) ? " On" : " Off"]
" +// if(s == "encryption keys") +// dat += "Channel Encryption Firmware[(encryptmod) ? " On" : " Off"]
" +// if(s == "universal translator") +// var/datum/language_holder/H = get_language_holder() +// dat += "Universal Translator[H.omnitongue ? " On" : " Off"]
" +// if(s == "projection array") +// dat += "Projection Array
" +// if(s == "camera jack") +// dat += "Camera Jack
" +// if(s == "door jack") +// dat += "Door Jack
" +// dat += "
" +// dat += "
" +// dat += "Download additional software" +// return dat +// +// +// +///mob/living/silicon/pai/proc/downloadSoftware() +// var/dat = "" +// +// dat += "

CentCom pAI Module Subversion Network


" +// dat += "
Remaining Available Memory: [ram]

" +// dat += "

Trunks available for checkout
" +// +// for(var/s in available_software) +// if(!software.Find(s)) +// var/cost = available_software[s] +// var/displayName = uppertext(s) +// dat += "[displayName] ([cost])
" +// else +// var/displayName = lowertext(s) +// dat += "[displayName] (Download Complete)
" +// dat += "

" +// return dat +// +// +///mob/living/silicon/pai/proc/directives() +// var/dat = "" +// +// dat += "[(master) ? "Your master: [master] ([master_dna])" : "You are bound to no one."]" +// dat += "

" +// dat += "Request carrier DNA sample
" +// dat += "

Directives


" +// dat += "Prime Directive
" +// dat += "     [laws.zeroth]
" +// dat += "Supplemental Directives
" +// for(var/slaws in laws.supplied) +// dat += "     [slaws]
" +// dat += "
" +// dat += {"

Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of +// comprehending the subtle nuances of human language. You may parse the \"spirit\" of a directive and follow its intent, +// rather than tripping over pedantics and getting snared by technicalities. Above all, you are machine in name and build +// only. In all other aspects, you may be seen as the ideal, unwavering human companion that you are.



+// Your prime directive comes before all others. Should a supplemental directive conflict with it, you are capable of +// simply discarding this inconsistency, ignoring the conflicting supplemental directive and continuing to fulfill your +// prime directive to the best of your ability.



- +// "} +// return dat /mob/living/silicon/pai/proc/CheckDNA(mob/living/carbon/M, mob/living/silicon/pai/P) if(!istype(M)) @@ -443,219 +443,220 @@ // -=-=-=-= Software =-=-=-=-=- // //Remote Signaller -/mob/living/silicon/pai/proc/softwareSignal() - var/dat = "" - dat += "

Remote Signaller



" - dat += {"Frequency/Code for signaler:
- Frequency: - - - - - [format_frequency(signaler.frequency)] - + - +
- - Code: - - - - - [signaler.code] - + - +
- - Send Signal
"} - return dat - -// Crew Manifest -/mob/living/silicon/pai/proc/softwareManifest() - . += "

Crew Manifest



" - if(GLOB.data_core.general) - for(var/datum/data/record/t in sortRecord(GLOB.data_core.general)) - . += "[t.fields["name"]] - [t.fields["rank"]]
" - . += "" - return . - -// Medical Records -/mob/living/silicon/pai/proc/softwareMedicalRecord() - switch(subscreen) - if(0) - . += "

Medical Records


" - if(GLOB.data_core.general) - for(var/datum/data/record/R in sortRecord(GLOB.data_core.general)) - . += "[R.fields["id"]]: [R.fields["name"]]
" - if(1) - . += "
Medical Record

" - if(medicalActive1 in GLOB.data_core.general) - . += "Name: [medicalActive1.fields["name"]] ID: [medicalActive1.fields["id"]]
\nGender: [medicalActive1.fields["gender"]]
\nAge: [medicalActive1.fields["age"]]
\nFingerprint: [medicalActive1.fields["fingerprint"]]
\nPhysical Status: [medicalActive1.fields["p_stat"]]
\nMental Status: [medicalActive1.fields["m_stat"]]
" - else - . += "
Requested medical record not found.

" - if(medicalActive2 in GLOB.data_core.medical) - . += "
\n
Medical Data

\nBlood Type:
[medicalActive2.fields["blood_type"]]
\nDNA: [medicalActive2.fields["b_dna"]]
\n
\nMinor Disabilities: [medicalActive2.fields["mi_dis"]]
\nDetails: [medicalActive2.fields["mi_dis_d"]]
\n
\nMajor Disabilities: [medicalActive2.fields["ma_dis"]]
\nDetails: [medicalActive2.fields["ma_dis_d"]]
\n
\nAllergies: [medicalActive2.fields["alg"]]
\nDetails: [medicalActive2.fields["alg_d"]]
\n
\nCurrent Diseases: [medicalActive2.fields["cdi"]] (per disease info placed in log/comment section)
\nDetails: [medicalActive2.fields["cdi_d"]]
\n
\nImportant Notes:
\n\t[medicalActive2.fields["notes"]]
\n
\n
Comments/Log

" - else - . += "
Requested medical record not found.

" - . += "
\nBack
" - return . - -// Security Records -/mob/living/silicon/pai/proc/softwareSecurityRecord() - . = "" - switch(subscreen) - if(0) - . += "

Security Records


" - if(GLOB.data_core.general) - for(var/datum/data/record/R in sortRecord(GLOB.data_core.general)) - . += "[R.fields["id"]]: [R.fields["name"]]
" - if(1) - . += "

Security Record

" - if(securityActive1 in GLOB.data_core.general) - . += "Name:
[securityActive1.fields["name"]] ID: [securityActive1.fields["id"]]
\nGender: [securityActive1.fields["gender"]]
\nAge: [securityActive1.fields["age"]]
\nRank: [securityActive1.fields["rank"]]
\nFingerprint: [securityActive1.fields["fingerprint"]]
\nPhysical Status: [securityActive1.fields["p_stat"]]
\nMental Status: [securityActive1.fields["m_stat"]]
" - else - . += "
Requested security record not found,

" - if(securityActive2 in GLOB.data_core.security) - . += "
" - . += "Security Data
" - . += "Criminal Status: [securityActive2.fields["criminal"]]

" - . += "Crimes:
" - for(var/datum/data/crime/crime in securityActive2.fields["crimes"]) - . += "\t[crime.crimeName]: [crime.crimeDetails]
" - . += "
" - . += "Important Notes:
" - . += "\t[securityActive2.fields["notes"]]

" - . += "
Comments/Log

" - for(var/datum/data/comment/comment in securityActive2.fields["comments"]) - . += "\t[comment.commentText] - [comment.author] [comment.time]
" - else - . += "
Requested security record not found,

" - . += "
\nBack
" - return . - -// Encryption Keys -/mob/living/silicon/pai/proc/softwareEncryptionKeys() - var/dat = {"

Encryption Key Firmware


- When enabled, this device will be able to use up to two (2) encryption keys for departmental channel access.

- The device is currently [encryptmod ? "en" : "dis" ]abled.
[encryptmod ? "" : "Activate Encryption Key Ports
"]"} - return dat - - -// Universal Translator -/mob/living/silicon/pai/proc/softwareTranslator() - var/datum/language_holder/H = get_language_holder() - . = {"

Universal Translator


- When enabled, this device will permamently be able to speak and understand all known forms of communication.

- The device is currently [H.omnitongue ? "en" : "dis" ]abled.
[H.omnitongue ? "" : "Activate Translation Module
"]"} - return . - -// Security HUD -/mob/living/silicon/pai/proc/facialRecognition() - var/dat = {"

Facial Recognition Overlay


- When enabled, this package will scan all viewable faces and compare them against the known criminal database, providing real-time graphical data about any detected persons of interest.

- The package is currently [ (secHUD) ? "en" : "dis" ]abled.
- Toggle Package
- "} - return dat - -// Medical HUD -/mob/living/silicon/pai/proc/medicalAnalysis() - var/dat = "" - dat += {"

Medical Analysis Overlay


- When enabled, this package will scan all nearby crewmembers' vitals and provide real-time graphical data about their state of health.

- The suite is currently [ (medHUD) ? "en" : "dis" ]abled.
- Toggle Suite
- "} - return dat - -//Health Scanner -/mob/living/silicon/pai/proc/softwareHostScan() - - var/dat = "" - dat += {"

Host Bisoscan Settings


- - Change Scan Type
- - "} - return dat -// Atmospheric Scanner -/mob/living/silicon/pai/proc/softwareAtmo() - var/dat = "

Atmospheric Sensor

" - - var/turf/T = get_turf(loc) - if (isnull(T)) - dat += "Unable to obtain a reading.
" - else - var/datum/gas_mixture/environment = T.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() - - dat += "Air Pressure: [round(pressure,0.1)] kPa
" - - if (total_moles) - for(var/id in environment.get_gases()) - var/gas_level = environment.get_moles(id)/total_moles - if(gas_level > 0.01) - dat += "[GLOB.gas_data.labels[id]]: [round(gas_level*100)]%
" - dat += "Temperature: [round(environment.return_temperature()-T0C)]°C
" - dat += "Refresh Reading
" - dat += "
" - return dat - -// Camera Jack - Clearly not finished -/mob/living/silicon/pai/proc/softwareCamera() - var/dat = "

Camera Jack

" - dat += "Cable status : " - - if(!cable) - dat += "Retracted
" - return dat - if(!cable.machine) - dat += "Extended
" - return dat - - var/obj/machinery/machine = cable.machine - dat += "Connected
" - - if(!istype(machine, /obj/machinery/camera)) - to_chat(src, "DERP") - return dat - -// Door Jack -/mob/living/silicon/pai/proc/softwareDoor() - var/dat = "

Airlock Jack

" - dat += "Cable status : " - if(!cable) - dat += "Retracted
" - dat += "Extend Cable
" - return dat - if(!cable.machine) - dat += "Extended
" - return dat - - var/obj/machinery/machine = cable.machine - dat += "Connected
" - if(!istype(machine, /obj/machinery/door)) - dat += "Connected device's firmware does not appear to be compatible with Airlock Jack protocols.
" - return dat - - if(!hackdoor) - dat += "Begin Airlock Jacking
" - else - dat += "Jack in progress... [hackprogress]% complete.
" - dat += "Cancel Airlock Jack
" - return dat - -// Door Jack - supporting proc -/mob/living/silicon/pai/proc/hackloop() - var/turf/T = get_turf(src) - for(var/mob/living/silicon/ai/AI in GLOB.player_list) - if(T.loc) - to_chat(AI, "Network Alert: Brute-force encryption crack in progress in [T.loc].") - else - to_chat(AI, "Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location.") - hacking = TRUE - -// Loudness Booster -/mob/living/silicon/pai/proc/softwareLoudness() - if(!internal_instrument) - internal_instrument = new(src) - var/dat = "

Sound Synthesizer

" - dat += "Open Synthesizer Interface
" - dat += "Choose Instrument Type" - return dat +///mob/living/silicon/pai/proc/softwareSignal() +// var/dat = "" +// dat += "

Remote Signaller



" +// dat += {"Frequency/Code for signaler:
+// Frequency: +// - +// - +// [format_frequency(signaler.frequency)] +// + +// +
+// +// Code: +// - +// - +// [signaler.code] +// + +// +
+// +// Send Signal
"} +// return dat +// +//// Crew Manifest +///mob/living/silicon/pai/proc/softwareManifest() +// . += "

Crew Manifest



" +// if(GLOB.data_core.general) +// for(var/datum/data/record/t in sortRecord(GLOB.data_core.general)) +// . += "[t.fields["name"]] - [t.fields["rank"]]
" +// . += "" +// return . +// +//// Medical Records +///mob/living/silicon/pai/proc/softwareMedicalRecord() +// switch(subscreen) +// if(0) +// . += "

Medical Records


" +// if(GLOB.data_core.general) +// for(var/datum/data/record/R in sortRecord(GLOB.data_core.general)) +// . += "[R.fields["id"]]: [R.fields["name"]]
" +// if(1) +// . += "
Medical Record

" +// if(medicalActive1 in GLOB.data_core.general) +// . += "Name: [medicalActive1.fields["name"]] ID: [medicalActive1.fields["id"]]
\nGender: [medicalActive1.fields["gender"]]
\nAge: [medicalActive1.fields["age"]]
\nFingerprint: [medicalActive1.fields["fingerprint"]]
\nPhysical Status: [medicalActive1.fields["p_stat"]]
\nMental Status: [medicalActive1.fields["m_stat"]]
" +// else +// . += "
Requested medical record not found.

" +// if(medicalActive2 in GLOB.data_core.medical) +// . += "
\n
Medical Data

\nBlood Type:
[medicalActive2.fields["blood_type"]]
\nDNA: [medicalActive2.fields["b_dna"]]
\n
\nMinor Disabilities: [medicalActive2.fields["mi_dis"]]
\nDetails: [medicalActive2.fields["mi_dis_d"]]
\n
\nMajor Disabilities: [medicalActive2.fields["ma_dis"]]
\nDetails: [medicalActive2.fields["ma_dis_d"]]
\n
\nAllergies: [medicalActive2.fields["alg"]]
\nDetails: [medicalActive2.fields["alg_d"]]
\n
\nCurrent Diseases: [medicalActive2.fields["cdi"]] (per disease info placed in log/comment section)
\nDetails: [medicalActive2.fields["cdi_d"]]
\n
\nImportant Notes:
\n\t[medicalActive2.fields["notes"]]
\n
\n
Comments/Log

" +// else +// . += "
Requested medical record not found.

" +// . += "
\nBack
" +// return . +// +//// Security Records +///mob/living/silicon/pai/proc/softwareSecurityRecord() +// . = "" +// switch(subscreen) +// if(0) +// . += "

Security Records


" +// if(GLOB.data_core.general) +// for(var/datum/data/record/R in sortRecord(GLOB.data_core.general)) +// . += "[R.fields["id"]]: [R.fields["name"]]
" +// if(1) +// . += "

Security Record

" +// if(securityActive1 in GLOB.data_core.general) +// . += "Name:
[securityActive1.fields["name"]] ID: [securityActive1.fields["id"]]
\nGender: [securityActive1.fields["gender"]]
\nAge: [securityActive1.fields["age"]]
\nRank: [securityActive1.fields["rank"]]
\nFingerprint: [securityActive1.fields["fingerprint"]]
\nPhysical Status: [securityActive1.fields["p_stat"]]
\nMental Status: [securityActive1.fields["m_stat"]]
" +// else +// . += "
Requested security record not found,

" +// if(securityActive2 in GLOB.data_core.security) +// . += "
" +// . += "Security Data
" +// . += "Criminal Status: [securityActive2.fields["criminal"]]

" +// . += "Crimes:
" +// for(var/datum/data/crime/crime in securityActive2.fields["crimes"]) +// . += "\t[crime.crimeName]: [crime.crimeDetails]
" +// . += "
" +// . += "Important Notes:
" +// . += "\t[securityActive2.fields["notes"]]

" +// . += "
Comments/Log

" +// for(var/datum/data/comment/comment in securityActive2.fields["comments"]) +// . += "\t[comment.commentText] - [comment.author] [comment.time]
" +// else +// . += "
Requested security record not found,

" +// . += "
\nBack
" +// return . +// +//// Encryption Keys +///mob/living/silicon/pai/proc/softwareEncryptionKeys() +// var/dat = {"

Encryption Key Firmware


+// When enabled, this device will be able to use up to two (2) encryption keys for departmental channel access.

+// The device is currently [encryptmod ? "en" : "dis" ]abled.
[encryptmod ? "" : "Activate Encryption Key Ports
"]"} +// return dat +// +// +//// Universal Translator +///mob/living/silicon/pai/proc/softwareTranslator() +// var/datum/language_holder/H = get_language_holder() +// . = {"

Universal Translator


+// When enabled, this device will permamently be able to speak and understand all known forms of communication.

+// The device is currently [H.omnitongue ? "en" : "dis" ]abled.
[H.omnitongue ? "" : "Activate Translation Module
"]"} +// return . +// +//// Security HUD +///mob/living/silicon/pai/proc/facialRecognition() +// var/dat = {"

Facial Recognition Overlay


+// When enabled, this package will scan all viewable faces and compare them against the known criminal database, providing real-time graphical data about any detected persons of interest.

+// The package is currently [ (secHUD) ? "en" : "dis" ]abled.
+// Toggle Package
+// "} +// return dat +// +//// Medical HUD +///mob/living/silicon/pai/proc/medicalAnalysis() +// var/dat = "" +// dat += {"

Medical Analysis Overlay


+// When enabled, this package will scan all nearby crewmembers' vitals and provide real-time graphical data about their state of health.

+// The suite is currently [ (medHUD) ? "en" : "dis" ]abled.
+// Toggle Suite
+// "} +// return dat +// +////Health Scanner +///mob/living/silicon/pai/proc/softwareHostScan() +// +// var/dat = "" +// dat += {"

Host Bisoscan Settings


+// +// Change Scan Type
+// +// "} +// return dat +//// Atmospheric Scanner +///mob/living/silicon/pai/proc/softwareAtmo() +// var/dat = "

Atmospheric Sensor

" +// +// var/turf/T = get_turf(loc) +// if (isnull(T)) +// dat += "Unable to obtain a reading.
" +// else +// var/datum/gas_mixture/environment = T.return_air() +// +// var/pressure = environment.return_pressure() +// var/total_moles = environment.total_moles() +// +// dat += "Air Pressure: [round(pressure,0.1)] kPa
" +// +// if (total_moles) +// for(var/id in environment.get_gases()) +// var/gas_level = environment.get_moles(id)/total_moles +// if(gas_level > 0.01) +// dat += "[GLOB.gas_data.labels[id]]: [round(gas_level*100)]%
" +// dat += "Temperature: [round(environment.return_temperature()-T0C)]°C
" +// dat += "Refresh Reading
" +// dat += "
" +// return dat +// +//// Camera Jack - Clearly not finished +///mob/living/silicon/pai/proc/softwareCamera() +// var/dat = "

Camera Jack

" +// dat += "Cable status : " +// +// if(!cable) +// dat += "Retracted
" +// return dat +// if(!cable.machine) +// dat += "Extended
" +// return dat +// +// var/obj/machinery/machine = cable.machine +// dat += "Connected
" +// +// if(!istype(machine, /obj/machinery/camera)) +// to_chat(src, "DERP") +// return dat +// +//// Door Jack +///mob/living/silicon/pai/proc/softwareDoor() +// var/dat = "

Airlock Jack

" +// dat += "Cable status : " +// if(!cable) +// dat += "Retracted
" +// dat += "Extend Cable
" +// return dat +// if(!cable.machine) +// dat += "Extended
" +// return dat +// +// var/obj/machinery/machine = cable.machine +// dat += "Connected
" +// if(!istype(machine, /obj/machinery/door)) +// dat += "Connected device's firmware does not appear to be compatible with Airlock Jack protocols.
" +// return dat +// +// if(!hackdoor) +// dat += "Begin Airlock Jacking
" +// else +// dat += "Jack in progress... [hackprogress]% complete.
" +// dat += "Cancel Airlock Jack
" +// return dat +// +//// Door Jack - supporting proc +///mob/living/silicon/pai/proc/hackloop() +// var/turf/T = get_turf(src) +// for(var/mob/living/silicon/ai/AI in GLOB.player_list) +// if(T.loc) +// to_chat(AI, "Network Alert: Brute-force encryption crack in progress in [T.loc].") +// else +// to_chat(AI, "Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location.") +// hacking = TRUE +// +//// Loudness Booster +///mob/living/silicon/pai/proc/softwareLoudness() +// if(!internal_instrument) +// internal_instrument = new(src) +// var/dat = "

Sound Synthesizer

" +// dat += "Open Synthesizer Interface
" +// dat += "Choose Instrument Type" +// return dat +// diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index ab703b57ab54..a168b409881c 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -7,11 +7,12 @@ type Module = { module_name: string; title: string; text: string; + cost: number; } type Data = { modules: Data[]; - modules_list: Data[]; + modules_list: Module[]; modules_tabs: Module[]; laws_zeroth: string; laws: Data[]; @@ -111,20 +112,25 @@ const PaiBox = (props, context) => { Downloaded modules: {modules.map(data => data)} + + Remaining available memory: {ram} - {modules_list.map(module => ( - - {module} - - ))} + + {modules_list.map(module => ( + + {module.module_name}: {module.cost} + + ))} +
); case "Remote signaller": return (
- + Signaller
); } From 75e7e1284a64c23ff93b28f25836ab5a26ad96b2 Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Tue, 15 Oct 2024 12:01:48 +0100 Subject: [PATCH 22/40] Buttons --- .../mob/living/silicon/pai/software.dm | 7 ++++ .../packages/tgui/interfaces/PaiInterface.tsx | 37 +++++++++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index c4b06898276e..88e8d9e6015c 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -45,6 +45,7 @@ data["modules"] = list() data["modules_list"] = available_software data["modules_tabs"] = list(list("module_name" = "Directives", "title"="Directives"), + list("module_name" = "Screen Display", "title"="Screen Display"), list("module_name" = "Download additional software", "title"="CentCom pAI Module Subversion Network")) data["laws_zeroth"] = laws.zeroth data["laws"] = laws.supplied @@ -58,11 +59,17 @@ return switch(action) if("getdna") + //This is probably breaking because it's using loc again + message_admins(card.loc) if(iscarbon(card.loc)) CheckDNA(card.loc, src) //you should only be able to check when directly in hand, muh immersions? else to_chat(src, "You are not being carried by anyone!") return 0 // FALSE ? If you return here you won't call paiinterface() below + if("encryptionkeys") + encryptmod = TRUE + if("translator") + grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE) update_appearance(UPDATE_ICON) ///mob/living/silicon/pai/proc/paiInterface() diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index a168b409881c..63ee2c552c2e 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -1,6 +1,6 @@ import { capitalize } from 'common/string'; import { useBackend, useLocalState } from '../backend'; -import { Box, Button, Section, Flex, Tabs, Stack, BlockQuote } from '../components'; +import { Box, Button, Section, Flex, Tabs, Stack, BlockQuote, Table, Dropdown } from '../components'; import { Window } from '../layouts'; type Module = { @@ -55,6 +55,7 @@ export const PaiInterface = (props, context) => { const PaiBox = (props, context) => { const { act, data } = useBackend(context); const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", null); + const [hoveredModule, sethoveredModule] = useLocalState(context, "hoveredModule", {}); const { modules, ram, modules_list } = data; const { laws_zeroth, laws, master, masterdna } = data; if(selectedMainTab===null) { @@ -106,6 +107,15 @@ const PaiBox = (props, context) => {
); + case "Screen Display": + return ( +
+ Select your new display image. + + + +
+ ) case "Download additional software": return (
@@ -117,12 +127,25 @@ const PaiBox = (props, context) => { Remaining available memory: {ram} - {modules_list.map(module => ( - - {module.module_name}: {module.cost} - - ))} + + {modules_list.map(module => ( + + + {module.module_name} + + +
From fdc125ef4d3b7da578f582a2f59c38f604c54e7c Mon Sep 17 00:00:00 2001 From: Oblisk234 <61151679+Oblisk234@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:56:06 +0100 Subject: [PATCH 23/40] Semi-working software downloads --- .../mob/living/silicon/pai/software.dm | 69 ++++++++++++------- .../packages/tgui/interfaces/PaiInterface.tsx | 17 ++--- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 88e8d9e6015c..60d7e3c9db3c 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -11,25 +11,25 @@ //radiation eyes //chem goggs //mesons - list("module_name" = "crew manifest", "cost" = 5), - list("module_name" = "digital messenger", "cost" = 5), - list("module_name" = "atmosphere sensor", "cost" = 5), - list("module_name" = "photography module", "cost" = 5), - list("module_name" = "remote signaller", "cost" = 10), - list("module_name" = "medical records", "cost" = 10), - list("module_name" = "security records", "cost" = 10), - list("module_name" = "camera zoom", "cost" = 10), - list("module_name" = "host scan", "cost" = 10), + list("module_name" = "crew manifest", "tab"=FALSE, "cost" = 5), + list("module_name" = "digital messenger", "tab"=FALSE, "cost" = 5), + list("module_name" = "atmosphere sensor", "tab"=TRUE, "cost" = 5), + list("module_name" = "photography module", "tab"=FALSE, "cost" = 5), + list("module_name" = "remote signaller", "tab"=TRUE, "cost" = 10), + list("module_name" = "medical records", "tab"=TRUE, "cost" = 10), + list("module_name" = "security records", "tab"=TRUE, "cost" = 10), + list("module_name" = "camera zoom", "tab"=FALSE, "cost" = 10), + list("module_name" = "host scan", "tab"=TRUE, "cost" = 10), //"camera jack" = 10, //"heartbeat sensor" = 10, //"projection array" = 15, - list("module_name" = "medical HUD", "cost" = 20), - list("module_name" = "security HUD", "cost" = 20), - list("module_name" = "loudness booster", "cost" = 20), - list("module_name" = "newscaster", "cost" = 20), - list("module_name" = "door jack", "cost" = 25), - list("module_name" = "encryption keys", "cost" = 25), - list("module_name" = "universal translator", "cost" = 35) + list("module_name" = "medical HUD", "tab"=FALSE, "cost" = 20), + list("module_name" = "security HUD", "tab"=FALSE, "cost" = 20), + list("module_name" = "loudness booster", "tab"=TRUE, "cost" = 20), + list("module_name" = "newscaster", "tab"=FALSE, "cost" = 20), + list("module_name" = "door jack", "tab"=TRUE, "cost" = 25), + list("module_name" = "encryption keys", "tab"=FALSE, "cost" = 25), + list("module_name" = "universal translator", "tab"=FALSE, "cost" = 35) ) /mob/living/silicon/pai/ui_interact(mob/user, datum/tgui/ui) @@ -42,7 +42,7 @@ /mob/living/silicon/pai/ui_data(mob/user) var/list/data = list() - data["modules"] = list() + data["modules"] = software data["modules_list"] = available_software data["modules_tabs"] = list(list("module_name" = "Directives", "title"="Directives"), list("module_name" = "Screen Display", "title"="Screen Display"), @@ -59,19 +59,38 @@ return switch(action) if("getdna") - //This is probably breaking because it's using loc again - message_admins(card.loc) - if(iscarbon(card.loc)) - CheckDNA(card.loc, src) //you should only be able to check when directly in hand, muh immersions? + message_admins(get(card, /mob/living/carbon/human)) //No way to test if get() works since UI buttons doesn't work currently if in card form + if(iscarbon(get(card, /mob/living/carbon/human))) + CheckDNA(get(card, /mob/living/carbon/human), src) //you should only be able to check when directly in hand, muh immersions? else to_chat(src, "You are not being carried by anyone!") return 0 // FALSE ? If you return here you won't call paiinterface() below - if("encryptionkeys") - encryptmod = TRUE - if("translator") - grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE) + if("buy") + message_admins(params["name"]) + message_admins(params["cost"]) + if(!software.Find(params["name"])) + software.Add(params["name"]) + ram -= params["cost"] + if(params["name"] == "medical HUD") + var/datum/atom_hud/med = GLOB.huds[med_hud] + med.show_to(src) + if(params["name"] == "security HUD") + var/datum/atom_hud/sec = GLOB.huds[sec_hud] + sec.show_to(src) + if(params["name"] == "encryption keys") + encryptmod = TRUE + if(params["name"] == "universal translator") + grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE) + var/datum/hud/pai/pAIhud = hud_used + pAIhud?.update_software_buttons() + available_software.Remove(available_software.Find(params["name"])) //Removes from downloadable software list so they can't be redownloaded + else //Should not be possible, but in the edge case that it does... + to_chat(usr, "Module already downloaded!") update_appearance(UPDATE_ICON) +/mob/living/silicon/pai/ui_state(mob/user) + return GLOB.always_state + ///mob/living/silicon/pai/proc/paiInterface() // // var/dat = "" diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index 63ee2c552c2e..d3042f2453c1 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -64,7 +64,7 @@ const PaiBox = (props, context) => { switch(selectedMainTab.module_name) { case "Directives": return ( -
+
{!master && ( @@ -82,7 +82,7 @@ const PaiBox = (props, context) => { - Prime directive: + Prime Directive: {laws_zeroth} @@ -109,16 +109,13 @@ const PaiBox = (props, context) => { ); case "Screen Display": return ( -
+
Select your new display image. - - -
- ) + ); case "Download additional software": return ( -
+
Downloaded modules: {modules.map(data => data)} @@ -137,11 +134,11 @@ const PaiBox = (props, context) => { +
+ )} + {!!screen && ( +
+
If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.
+ {candidates.map(candidate => ( +
+ Name: {candidate.name} + Description: {candidate.description} + Preferred role: {candidate.prefrole} + OOC comments: {candidate.ooccomments} + +
+ ))} + +
+ )} + + ); + } +}; + +export const PaiManagement = (props, context) => { + const { act, data } = useBackend(context); + const { name, master, masterdna } = data; + const { laws_zeroth, laws } = data; + const { transmit, receive, holomatrix, modules, ram } = data; + return ( +
+ + Master: + {!!master && ( + {master} ({masterdna}) + )} + {!master && ( + + None + + + )} + + Prime Directive: + {laws_zeroth} + + + Additional directives: + {laws.map(data => data)} + + {/* Without the box, Stack will make this button fluid for some reason */} + + Radio Uplink: + act("radio", { radio: 1 })} checked={transmit}>Transmit + act("radio", { radio: 0 })} checked={receive}>Receive + + + Other: + act("holomatrix")} checked={holomatrix}>Holomatrix projectors + + + + Downloaded modules: ({ram} GQ) + {modules.length === 0 && ( + + No downloaded modules. + + )} + {modules.length !== 0 && modules.map(module => ( + + {module} + + ))} + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/PaiInterface.tsx b/tgui/packages/tgui/interfaces/PaiInterface.tsx index 8155329777c2..8ad17f9998e3 100644 --- a/tgui/packages/tgui/interfaces/PaiInterface.tsx +++ b/tgui/packages/tgui/interfaces/PaiInterface.tsx @@ -7,7 +7,6 @@ import { Window } from '../layouts'; type Module = { module_name: string; title: string; - text: string; cost: number; } @@ -16,17 +15,17 @@ type Data = { modules_list: Module[]; modules_tabs: Module[]; laws_zeroth: string; - laws: Data[]; + laws: string[]; master: string; masterdna: string; ram: number; pressure: number; - gases: Data[]; + gases: string[]; temperature: number; hacking: boolean; hackprogress: number; cable: string; - door: Data[]; + door: string[]; code: number; frequency: number; minFrequency: number; @@ -54,7 +53,7 @@ export const PaiInterface = (props, context) => { const { modules_tabs = [] } = data; const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", 0); return ( - + @@ -83,14 +82,13 @@ export const PaiInterface = (props, context) => { const PaiBox = (props, context) => { const { act, data } = useBackend(context); const [selectedMainTab, setMainTab] = useLocalState(context, "selectedMainTab", 0); - const [hoveredModule, sethoveredModule] = useLocalState(context, "hoveredModule", {}); const { modules, ram, modules_list, modules_tabs = [] } = data; const { laws_zeroth, laws, master, masterdna } = data; const { pressure, gases, temperature } = data; const { hacking, hackprogress, cable, door } = data; const { code, frequency, minFrequency, maxFrequency, color } = data; - if(selectedMainTab===null) { - return; + if(!modules_tabs[selectedMainTab]) { + return null; } switch(modules_tabs[selectedMainTab].module_name) { case "directives": @@ -191,9 +189,6 @@ const PaiBox = (props, context) => {