diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm
index 8a9945d1d1d..8325c2460ad 100644
--- a/code/game/gamemodes/objective_items.dm
+++ b/code/game/gamemodes/objective_items.dm
@@ -365,7 +365,8 @@
// SKYRAT REMOVAL START - MOD PAI
/*else if(istype(potential_storage, /obj/item/mod/control))
var/obj/item/mod/control/suit = potential_storage
- being = suit.ai
+ if(isAI(suit.ai_assistant))
+ being = suit.ai_assistant
*/ // SKYRAT REMOVAL END
else
stack_trace("check_special_completion() called on [src] with [potential_storage] ([potential_storage.type])! That's not supposed to happen!")
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 767f215cbf6..0ca75c35850 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -302,14 +302,16 @@
LAZYADD(actions, action)
RegisterSignal(action, COMSIG_QDELETING, PROC_REF(on_action_deleted))
- if(ismob(loc))
- // We're being held or are equipped by someone while adding an action?
- // Then they should also probably be granted the action, given it's in a correct slot
- var/mob/holder = loc
- give_item_action(action, holder, holder.get_slot_by_item(src))
-
+ grant_action_to_bearer(action)
return action
+/// Grant the action to anyone who has this item equipped to an appropriate slot
+/obj/item/proc/grant_action_to_bearer(datum/action/action)
+ if(!ismob(loc))
+ return
+ var/mob/holder = loc
+ give_item_action(action, holder, holder.get_slot_by_item(src))
+
/// Removes an instance of an action from our list of item actions.
/obj/item/proc/remove_item_action(datum/action/action)
if(!action)
diff --git a/code/modules/mod/mod_actions.dm b/code/modules/mod/mod_actions.dm
index eca29c8293e..d82912055e2 100644
--- a/code/modules/mod/mod_actions.dm
+++ b/code/modules/mod/mod_actions.dm
@@ -11,24 +11,22 @@
if(!istype(Target, /obj/item/mod/control))
qdel(src)
return
- // SKYRAT EDIT START - pAIs in MODsuits
- if(pai_action)
- background_icon_state = "bg_tech"
- // SKYRAT EDIT END
+ if(ai_action)
+ background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND
/datum/action/item_action/mod/Grant(mob/user)
var/obj/item/mod/control/mod = target
- if(pai_action && user != mod.mod_pai) // SKYRAT EDIT - pAIs in MODsuits
+ if(ai_action && user != mod.ai_assistant)
return
- else if(!pai_action && user == mod.mod_pai) // SKYRAT EDIT - pAIs in MODsuits
+ else if(!ai_action && user == mod.ai_assistant)
return
return ..()
/datum/action/item_action/mod/Remove(mob/user)
var/obj/item/mod/control/mod = target
- if(pai_action && user != mod.mod_pai) // SKYRAT EDIT - pAIs in MODsuits
+ if(ai_action && user != mod.ai_assistant)
return
- else if(!pai_action && user == mod.mod_pai) // SKYRAT EDIT - pAIs in MODsuits
+ else if(!ai_action && user == mod.ai_assistant)
return
return ..()
@@ -125,40 +123,36 @@
var/override = FALSE
/// Module we are linked to.
var/obj/item/mod/module/module
- /// A ref to the mob we are pinned to.
- var/pinner_ref
+ /// A reference to the mob we are pinned to.
+ var/mob/pinner
/datum/action/item_action/mod/pinned_module/New(Target, obj/item/mod/module/linked_module, mob/user)
- // SKYRAT EDIT START - pAIs in MODsuits
- var/obj/item/mod/control/mod = Target // We have to do this otherwise it's going to runtime
- if(user == mod.mod_pai)
- pai_action = TRUE
- // SKYRAT EDIT END
- if(isAI(user))
+ var/obj/item/mod/control/mod = Target
+ if(user == mod.ai_assistant)
ai_action = TRUE
button_icon = linked_module.icon
button_icon_state = linked_module.icon_state
- ..()
+ . = ..()
module = linked_module
+ pinner = user
+ module.pinned_to[REF(user)] = src
if(linked_module.allow_flags & MODULE_ALLOW_INCAPACITATED)
// clears check hands and check conscious
check_flags = NONE
name = "Activate [capitalize(linked_module.name)]"
desc = "Quickly activate [linked_module]."
RegisterSignals(linked_module, list(COMSIG_MODULE_ACTIVATED, COMSIG_MODULE_DEACTIVATED, COMSIG_MODULE_USED), PROC_REF(module_interacted_with))
+ RegisterSignal(user, COMSIG_QDELETING, PROC_REF(pinner_deleted))
/datum/action/item_action/mod/pinned_module/Destroy()
UnregisterSignal(module, list(COMSIG_MODULE_ACTIVATED, COMSIG_MODULE_DEACTIVATED, COMSIG_MODULE_USED))
- module.pinned_to -= pinner_ref
+ module.pinned_to -= REF(pinner)
module = null
+ pinner = null
return ..()
/datum/action/item_action/mod/pinned_module/Grant(mob/user)
- var/user_ref = REF(user)
- if(!pinner_ref)
- pinner_ref = user_ref
- module.pinned_to[pinner_ref] = src
- else if(pinner_ref != user_ref)
+ if(pinner != user)
return
return ..()
@@ -168,6 +162,11 @@
return
module.on_select()
+/// If the guy whose UI we are pinned to got deleted
+/datum/action/item_action/mod/pinned_module/proc/pinner_deleted()
+ pinner = null
+ qdel(src)
+
/datum/action/item_action/mod/pinned_module/apply_button_overlay(atom/movable/screen/movable/action_button/current_button, force)
current_button.cut_overlays()
if(override)
diff --git a/code/modules/mod/mod_activation.dm b/code/modules/mod/mod_activation.dm
index a9c24669a4c..37083aeb2c1 100644
--- a/code/modules/mod/mod_activation.dm
+++ b/code/modules/mod/mod_activation.dm
@@ -70,6 +70,9 @@
/// Deploys a part of the suit onto the user.
/obj/item/mod/control/proc/deploy(mob/user, obj/item/part)
+ if(!wearer)
+ playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
+ return FALSE // pAI is trying to deploy it from your hands
if(part.loc != src)
if(!user)
return FALSE
@@ -162,11 +165,9 @@
module.on_deactivation(display_message = FALSE)
activating = TRUE
to_chat(wearer, span_notice("MODsuit [active ? "shutting down" : "starting up"]."))
- // SKYRAT EDIT START - pAIs in MODsuits
- if(mod_pai)
- to_chat(mod_pai, span_notice("MODsuit [active ? "shutting down" : "starting up"]."))
- // SKYRAT EDIT END
+ if (ai_assistant)
+ to_chat(ai_assistant, span_notice("MODsuit [active ? "shutting down" : "starting up"]."))
if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
to_chat(wearer, span_notice("[boots] [active ? "relax their grip on your legs" : "seal around your feet"]."))
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
@@ -185,10 +186,8 @@
seal_part(helmet, seal = !active)
if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
to_chat(wearer, span_notice("Systems [active ? "shut down. Parts unsealed. Goodbye" : "started up. Parts sealed. Welcome"], [wearer]."))
- // SKYRAT EDIT START - pAIs in MODsuits
- if(mod_pai)
- to_chat(mod_pai, span_notice("SYSTEMS [active ? "DEACTIVATED. GOODBYE" : "ACTIVATED. WELCOME"]: \"[mod_pai]\""))
- // SKYRAT EDIT END
+ if(ai_assistant)
+ to_chat(ai_assistant, span_notice("SYSTEMS [active ? "DEACTIVATED. GOODBYE" : "ACTIVATED. WELCOME"]: \"[ai_assistant]\""))
finish_activation(on = !active)
if(active)
playsound(src, 'sound/machines/synth_yes.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000)
diff --git a/code/modules/mod/mod_ai.dm b/code/modules/mod/mod_ai.dm
index 97fdcd364ee..fb83518c562 100644
--- a/code/modules/mod/mod_ai.dm
+++ b/code/modules/mod/mod_ai.dm
@@ -1,43 +1,35 @@
-/* SKYRAT EDIT REMOVAL - pAIs in MODsuits
/obj/item/mod/control/transfer_ai(interaction, mob/user, mob/living/silicon/ai/intAI, obj/item/aicard/card)
. = ..()
if(!.)
return
+ // SKYRAT EDIT ADDITION START - No AIs in MODsuits
+ if(!allow_ai)
+ return
+ // SKYRAT EDIT END
if(!open) //mod must be open
balloon_alert(user, "suit must be open to transfer!")
return
switch(interaction)
if(AI_TRANS_TO_CARD)
- if(!ai)
+ if(!ai_assistant)
balloon_alert(user, "no ai in suit!")
return
balloon_alert(user, "transferring to card...")
if(!do_after(user, 5 SECONDS, target = src))
balloon_alert(user, "interrupted!")
return
- if(!ai)
+ if(!ai_assistant)
+ balloon_alert(user, "no ai in suit!")
return
- intAI = ai
- intAI.ai_restore_power()//So the AI initially has power.
- intAI.control_disabled = TRUE
- intAI.radio_enabled = FALSE
- intAI.disconnect_shell()
- intAI.forceMove(card)
- card.AI = intAI
- for(var/datum/action/action as anything in actions)
- action.Remove(intAI)
- intAI.controlled_equipment = null
- intAI.remote_control = null
- balloon_alert(intAI, "transferred to a card")
balloon_alert(user, "ai transferred to card")
- ai = null
+ ai_exit_mod(card)
if(AI_TRANS_FROM_CARD) //Using an AI card to upload to the suit.
intAI = card.AI
if(!intAI)
balloon_alert(user, "no ai in card!")
return
- if(ai)
+ if(ai_assistant)
balloon_alert(user, "already has ai!")
return
if(intAI.deployed_shell) //Recall AI if shelled so it can be checked for a client
@@ -49,12 +41,13 @@
if(!do_after(user, 5 SECONDS, target = src))
balloon_alert(user, "interrupted!")
return
- if(ai)
+ if(ai_assistant)
return
balloon_alert(user, "ai transferred to suit")
ai_enter_mod(intAI)
card.AI = null
+/// Place an AI in control of your suit functions
/obj/item/mod/control/proc/ai_enter_mod(mob/living/silicon/ai/new_ai)
new_ai.control_disabled = FALSE
new_ai.radio_enabled = TRUE
@@ -63,10 +56,84 @@
new_ai.controlled_equipment = src
new_ai.remote_control = src
new_ai.forceMove(src)
- ai = new_ai
- balloon_alert(new_ai, "transferred to a suit")
+ on_gained_assistant(new_ai)
+
+/// Remove an AI's control of your suit functions
+/obj/item/mod/control/proc/ai_exit_mod(obj/item/aicard/card)
+ var/mob/living/silicon/ai/old_ai = ai_assistant
+ old_ai.ai_restore_power()//So the AI initially has power.
+ old_ai.control_disabled = TRUE
+ old_ai.radio_enabled = FALSE
+ old_ai.disconnect_shell()
+ old_ai.forceMove(card)
+ card.AI = old_ai
+ old_ai.controlled_equipment = null
+ on_removed_assistant(old_ai)
+
+/// Place a pAI in control of your suit functions
+/obj/item/mod/control/proc/insert_pai(mob/user, obj/item/pai_card/card)
+ if (!isnull(ai_assistant))
+ balloon_alert(user, "slot occupied!")
+ return FALSE
+ if (isnull(card.pai?.mind))
+ balloon_alert(user, "pAI unresponsive!")
+ return FALSE
+ balloon_alert(user, "transferring to suit...")
+ if (!do_after(user, 5 SECONDS, target = src))
+ balloon_alert(user, "interrupted!")
+ return FALSE
+ if (!user.transferItemToLoc(card, src))
+ balloon_alert(user, "transfer failed!")
+ return FALSE
+ balloon_alert(user, "pAI transferred to suit")
+ var/mob/living/silicon/pai/pai_assistant = card.pai
+ pai_assistant.can_transmit = TRUE
+ pai_assistant.can_receive = TRUE
+ pai_assistant.can_holo = FALSE
+ if (pai_assistant.holoform)
+ pai_assistant.fold_in()
+ // SKYRAT EDIT ADDITION START - pAIs in MODsuits
+ if(can_pai_move_suit)
+ pai_assistant.remote_control = src
+ // SKYRAT EDIT END
+ SStgui.close_uis(card)
+ on_gained_assistant(card.pai)
+ return TRUE
+
+/// Removes pAI control from a modsuit
+/obj/item/mod/control/proc/remove_pai(mob/user, forced = FALSE)
+ if (isnull(ai_assistant))
+ balloon_alert(user, "no pAI!")
+ return FALSE
+ if (!forced)
+ if (!open)
+ balloon_alert(user, "suit panel closed!")
+ return FALSE
+ balloon_alert(user, "uninstalling card...")
+ if (!do_after(user, 5 SECONDS, target = src))
+ balloon_alert(user, "interrupted!")
+ return FALSE
+
+ balloon_alert(user, "pAI removed from suit")
+ var/mob/living/silicon/pai/pai_helper = ai_assistant
+ pai_helper.can_holo = TRUE
+ pai_helper.card.forceMove(get_turf(src))
+ on_removed_assistant()
+
+/// Called when a new ai assistant is inserted
+/obj/item/mod/control/proc/on_gained_assistant(mob/living/silicon/new_helper)
+ ai_assistant = new_helper
+ balloon_alert(new_helper, "transferred to a suit")
for(var/datum/action/action as anything in actions)
- action.Grant(new_ai)
+ action.Grant(new_helper)
+
+/// Called when an existing ai assistant is removed
+/obj/item/mod/control/proc/on_removed_assistant()
+ for(var/datum/action/action as anything in actions)
+ action.Remove(ai_assistant)
+ ai_assistant.remote_control = null
+ balloon_alert(ai_assistant, "transferred to a card")
+ ai_assistant = null
#define MOVE_DELAY 2
#define WEARER_DELAY 1
@@ -75,8 +142,12 @@
#define AI_FALL_TIME (1 SECONDS)
/obj/item/mod/control/relaymove(mob/user, direction)
- if((!active && wearer) || get_charge() < CHARGE_PER_STEP || user != ai || !COOLDOWN_FINISHED(src, cooldown_mod_move) || (wearer?.pulledby?.grab_state > GRAB_PASSIVE))
+ if((!active && wearer) || get_charge() < CHARGE_PER_STEP || user != ai_assistant || !COOLDOWN_FINISHED(src, cooldown_mod_move) || (wearer?.pulledby?.grab_state > GRAB_PASSIVE))
return FALSE
+ // SKYRAT EDIT START - pAIs in MODsuits with a bit more functionalities
+ if(active && !can_pai_move_suit && ispAI(ai_assistant))
+ return FALSE
+ // SKYRAT EDIT END
var/timemodifier = MOVE_DELAY * (ISDIAGONALDIR(direction) ? sqrt(2) : 1) * (wearer ? WEARER_DELAY : LONE_DELAY)
if(wearer && !wearer.Process_Spacemove(direction))
return FALSE
@@ -112,8 +183,10 @@
/obj/item/mod/ai_minicard/Initialize(mapload, mob/living/silicon/ai/ai)
. = ..()
- if(!ai)
+ if(isnull(ai))
return
+ ai.controlled_equipment = null
+ ai.remote_control = null
ai.apply_damage(150, BURN)
INVOKE_ASYNC(ai, TYPE_PROC_REF(/mob/living/silicon/ai, death))
ai.forceMove(src)
@@ -149,4 +222,3 @@
balloon_alert(user, "ai transferred to card")
stored_ai = null
#undef AI_FALL_TIME
-*/
diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm
index bdc4ce75cf6..5cce89f1511 100644
--- a/code/modules/mod/mod_control.dm
+++ b/code/modules/mod/mod_control.dm
@@ -21,10 +21,10 @@
/datum/action/item_action/mod/sprite_accessories, // SKYRAT EDIT - Hide mutant parts action
/datum/action/item_action/mod/panel,
/datum/action/item_action/mod/module,
- /datum/action/item_action/mod/deploy/pai, // SKYRAT EDIT - pAIs in MODsuits
- /datum/action/item_action/mod/activate/pai, // SKYRAT EDIT - pAIs in MODsuits
- /datum/action/item_action/mod/panel/pai, // SKYRAT EDIT - pAIs in MODsuits
- /datum/action/item_action/mod/module/pai, // SKYRAT EDIT - pAIs in MODsuits
+ /datum/action/item_action/mod/deploy/ai,
+ /datum/action/item_action/mod/activate/ai,
+ /datum/action/item_action/mod/panel/ai,
+ /datum/action/item_action/mod/module/ai,
)
resistance_flags = NONE
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
@@ -83,10 +83,8 @@
var/list/modules = list()
/// Currently used module.
var/obj/item/mod/module/selected_module
- /* SKYRAT EDIT REMOVAL - MODsuit pAIs
- /// AI mob inhabiting the MOD.
- var/mob/living/silicon/ai/ai
- */ // SKYRAT EDIT END
+ /// AI or pAI mob inhabiting the MOD.
+ var/mob/living/silicon/ai_assistant
/// Delay between moves as AI.
var/static/movedelay = 0
/// Cooldown for AI moves.
@@ -189,7 +187,14 @@
var/obj/item/overslot = overslotting_parts[part]
overslot.forceMove(drop_location())
overslotting_parts[part] = null
- remove_pai() // SKYRAT EDIT - pAIs in MODsuits
+ if(ai_assistant)
+ if(ispAI(ai_assistant))
+ INVOKE_ASYNC(src, PROC_REF(remove_pai), /* user = */ null, /* forced = */ TRUE) // async to appease spaceman DMM because the branch we don't run has a do_after
+ else
+ for(var/datum/action/action as anything in actions)
+ if(action.owner == ai_assistant)
+ action.Remove(ai_assistant)
+ new /obj/item/mod/ai_minicard(drop_location(), ai_assistant)
return ..()
/obj/item/mod/control/examine(mob/user)
@@ -211,12 +216,10 @@
. += span_notice("You could remove [core] with a wrench.")
else
. += span_notice("You could use a MOD core on it to install one.")
- if(!mod_pai) // SKYRAT EDIT BEGIN - PAI in Modsuits
- . += span_notice("You could install a pAI with a pAI card.")
-/* if(ai)
- . += span_notice("You could remove [ai] with an intellicard.")
- else
- . += span_notice("You could install an AI with an intellicard.") SKYRAT EDIT END */
+ if(isnull(ai_assistant))
+ . += span_notice("You could install a pAI with a pAI card.") // SKYRAT EDIT CHANGE - ORIGINAL: . += span_notice("You could install an AI or pAI using their storage card.")
+ else if(isAI(ai_assistant))
+ . += span_notice("You could remove [ai_assistant] with an intellicard.")
. += span_notice("You could examine it more thoroughly...")
/obj/item/mod/control/examine_more(mob/user)
@@ -256,6 +259,13 @@
if(slot & slot_flags)
return TRUE
+// Grant pinned actions to pin owners, gives AI pinned actions to the AI and not the wearer
+/obj/item/mod/control/grant_action_to_bearer(datum/action/action)
+ if (!istype(action, /datum/action/item_action/mod/pinned_module))
+ return ..()
+ var/datum/action/item_action/mod/pinned_module/pinned = action
+ give_item_action(action, pinned.pinner, slot_flags)
+
/obj/item/mod/control/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE)
. = ..()
if(!wearer || old_loc != wearer || loc == wearer)
@@ -317,10 +327,8 @@
return ..()
/obj/item/mod/control/screwdriver_act(mob/living/user, obj/item/screwdriver)
- // SKYRAT EDIT START - pAIs in MODsuits
. = ..()
if(.)
- // SKYRAT EDIT END
return TRUE
if(active || activating || ai_controller)
balloon_alert(user, "deactivate suit first!")
@@ -370,14 +378,12 @@
return FALSE
/obj/item/mod/control/attackby(obj/item/attacking_item, mob/living/user, params)
- // SKYRAT EDIT START - pAIs in MODsuits
if(istype(attacking_item, /obj/item/pai_card))
- if(!open) //mod must be open
- balloon_alert(user, "suit must be open to transfer!")
+ if(!open)
+ balloon_alert(user, "open the cover first!")
return FALSE
insert_pai(user, attacking_item)
return TRUE
- // SKYRAT EDIT END
if(istype(attacking_item, /obj/item/mod/module))
if(!open)
balloon_alert(user, "open the cover first!")
@@ -576,12 +582,6 @@
new_module.on_equip()
if(active)
new_module.on_suit_activation()
- // SKYRAT EDIT START - pAIs in MODsuits
- if(mod_pai)
- var/datum/action/item_action/mod/pinned_module/action = new_module.pinned_to[ref(mod_pai)]
- if(action)
- action.Grant(mod_pai)
- // SKYRAT EDIT END
if(user)
balloon_alert(user, "[new_module] added")
playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE)
diff --git a/code/modules/mod/mod_ui.dm b/code/modules/mod/mod_ui.dm
index 5c4e3328868..cbf30fe1611 100644
--- a/code/modules/mod/mod_ui.dm
+++ b/code/modules/mod/mod_ui.dm
@@ -12,7 +12,9 @@
"cell_charge_current" = get_charge(),
"cell_charge_max" = get_max_charge(),
"active" = active,
- //"ai_name" = ai?.name, // SKYRAT EDIT REMOVAL - pAIs in MODsuits
+ "ai_name" = ai_assistant?.name,
+ "has_pai" = ispAI(ai_assistant),
+ "is_ai" = ai_assistant && ai_assistant == user,
// Wires
"open" = open,
"seconds_electrified" = seconds_electrified,
@@ -21,10 +23,6 @@
"interface_break" = interface_break,
// Modules
"complexity" = complexity,
- // SKYRAT EDIT START - pAIs in MODsuits
- "pAI" = mod_pai?.name,
- "ispAI" = mod_pai ? mod_pai == user : FALSE,
- // SKYRAT EDIT END
)
data["suit_status"] = suit_status
// User information
@@ -69,12 +67,16 @@
data["boots"] = boots?.name
return data
+/obj/item/mod/control/ui_state(mob/user)
+ if(user == ai_assistant)
+ return GLOB.contained_state
+ return ..()
+
/obj/item/mod/control/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
- // allowed() doesn't allow for pAIs
- if(((locked && !ispAI(usr)) && !allowed(usr))) // SKYRAT EDIT CHANGE - ORIGINAL: if(locked && !allowed(usr))
+ if(locked && (!allowed(usr) || !ispAI(usr))) // pAIs automatically fail out of allowed()
balloon_alert(usr, "insufficient access!")
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
return
@@ -102,10 +104,8 @@
if(!module)
return
module.pin(usr)
- // SKYRAT EDIT START - pAIs in MODsuits
- if("remove_pai")
- if(ishuman(usr)) // Only the MODsuit's wearer should be removing the pAI.
- var/mob/user = usr
- extract_pai(user)
- // SKYRAT EDIT END
+ if("eject_pai")
+ if (!ishuman(usr))
+ return
+ remove_pai(usr)
return TRUE
diff --git a/code/modules/mod/modules/modules_ninja.dm b/code/modules/mod/modules/modules_ninja.dm
index 0b9a804dc52..9f6fd3b702d 100644
--- a/code/modules/mod/modules/modules_ninja.dm
+++ b/code/modules/mod/modules/modules_ninja.dm
@@ -257,11 +257,9 @@
. = ..()
if(. != MOD_CANCEL_ACTIVATE || !isliving(user))
return
- // SKYRAT EDIT CHANGE BEGIN - pAIs in MODsuits - `ai` replaced with `mod_pai`
- if(mod.mod_pai == user)
- to_chat(mod.mod_pai, span_danger("fATaL EERRoR: 381200-*#00CODE BLUE\nAI INTErFERenCE DEtECted\nACTi0N DISrEGArdED"))
+ if(mod.ai_assistant == user)
+ to_chat(mod.ai_assistant, span_danger("fATaL EERRoR: 381200-*#00CODE BLUE\nAI INTErFERenCE DEtECted\nACTi0N DISrEGArdED"))
return
- // SKYRAT EDIT CHANGE END
var/mob/living/living_user = user
to_chat(living_user, span_danger("fATaL EERRoR: 382200-*#00CODE RED\nUNAUTHORIZED USE DETECteD\nCoMMENCING SUB-R0UTIN3 13...\nTERMInATING U-U-USER..."))
living_user.investigate_log("has been gibbed by using a MODsuit equipped with [src].", INVESTIGATE_DEATHS)
diff --git a/modular_skyrat/modules/modsuit_pai/code/mod_pai.dm b/modular_skyrat/modules/modsuit_pai/code/mod_pai.dm
index 0732d1dd459..521fe7ebcc7 100644
--- a/modular_skyrat/modules/modsuit_pai/code/mod_pai.dm
+++ b/modular_skyrat/modules/modsuit_pai/code/mod_pai.dm
@@ -1,154 +1,8 @@
-/**
- * Simple proc to insert the pAI into the MODsuit.
- *
- * user - The person trying to put the pAI into the MODsuit.
- * card - The pAI card we're slotting in the MODsuit.
- */
-
-/obj/item/mod/control/proc/insert_pai(mob/user, obj/item/pai_card/card)
- if(mod_pai)
- balloon_alert(user, "pAI already installed!")
- return
- if(!card.pai || !card.pai.mind)
- balloon_alert(user, "pAI unresponsive!")
- return
- balloon_alert(user, "transferring to suit...")
- if(!do_after(user, 5 SECONDS, target = src))
- balloon_alert(user, "interrupted!")
- return FALSE
- if(!user.transferItemToLoc(card, src))
- return
-
- mod_pai = card.pai
- balloon_alert(user, "pAI transferred to suit")
- balloon_alert(mod_pai, "transferred to a suit")
- mod_pai.can_transmit = TRUE
- mod_pai.can_receive = TRUE
- mod_pai.can_holo = FALSE
- mod_pai.remote_control = src
- for(var/datum/action/action as anything in actions)
- action.Grant(mod_pai)
- return TRUE
-
-/**
- * Simple proc to extract the pAI from the MODsuit. It's the proc to call if you want to take it out,
- * remove_pai() is there so atom_destruction() doesn't have any risk of sleeping.
- *
- * user - The person trying to take out the pAI from the MODsuit.
- * forced - Whether or not we skip the checks and just eject the pAI. Defaults to FALSE.
- * feedback - Whether to give feedback via balloon alerts or not. Defaults to TRUE.
- */
-/obj/item/mod/control/proc/extract_pai(mob/user, forced = FALSE, feedback = TRUE)
- if(!mod_pai)
- if(user && feedback)
- balloon_alert(user, "no pAI to remove!")
- return
- if(!forced)
- if(!open)
- if(user && feedback)
- balloon_alert(user, "open the suit panel!")
- return FALSE
- if(!do_after(user, 5 SECONDS, target = src))
- if(user && feedback)
- balloon_alert(user, "interrupted!")
- return FALSE
-
- remove_pai(feedback)
-
- if(feedback && user)
- balloon_alert(user, "pAI removed from the suit")
-
-/**
- * Simple proc that handles the safe removal of the pAI from a MOD control unit.
- *
- * Arguments:
- * * feedback - Whether or not we want to give balloon alert feedback to the mod_pai. Defaults to FALSE.
- */
-/obj/item/mod/control/proc/remove_pai(feedback = FALSE)
- var/turf/drop_off = get_turf(src)
- if(drop_off) // In case there's no drop_off, the pAI will simply get deleted.
- mod_pai.card.forceMove(drop_off)
-
- for(var/datum/action/action as anything in actions)
- if(action.owner == mod_pai)
- action.Remove(mod_pai)
-
- if(feedback)
- balloon_alert(mod_pai, "removed from a suit")
- mod_pai.remote_control = null
- mod_pai.can_holo = TRUE
- mod_pai = null
-
-
-#define MOVE_DELAY 2
-#define WEARER_DELAY 1
-#define LONE_DELAY 5
-#define CELL_PER_STEP (DEFAULT_CHARGE_DRAIN * 2.5)
-#define PAI_FALL_TIME (1 SECONDS)
-
-/obj/item/mod/control/relaymove(mob/user, direction)
- if((!active && wearer) || (active && !can_pai_move_suit) || !core.charge_source() || core.charge_amount() < CELL_PER_STEP || user != mod_pai || !COOLDOWN_FINISHED(src, cooldown_mod_move))
- return FALSE
- if(wearer && (wearer.pulledby?.grab_state || wearer.incapacitated() || wearer.stat))
- return FALSE
- var/timemodifier = MOVE_DELAY * (ISDIAGONALDIR(direction) ? sqrt(2) : 1) * (wearer ? WEARER_DELAY : LONE_DELAY)
- COOLDOWN_START(src, cooldown_mod_move, movedelay * timemodifier + slowdown)
- playsound(src, 'sound/mecha/mechmove01.ogg', 25, TRUE)
- core.subtract_charge(CELL_PER_STEP)
- if(wearer)
- ADD_TRAIT(wearer, TRAIT_FORCED_STANDING, MOD_TRAIT)
- addtimer(CALLBACK(src, PROC_REF(pai_fall)), PAI_FALL_TIME, TIMER_UNIQUE | TIMER_OVERRIDE)
- if(ismovable(wearer?.loc))
- return wearer.loc.relaymove(wearer, direction)
- if(wearer && !wearer.Process_Spacemove(direction))
- return FALSE
- var/atom/movable/mover = wearer || src
- return mover.try_step_multiz(direction)
-
-#undef MOVE_DELAY
-#undef WEARER_DELAY
-#undef LONE_DELAY
-#undef CELL_PER_STEP
-#undef PAI_FALL_TIME
-
-/// Simple proc adding the falling of the MODsuit when it's no longer moving, for corpses and unconscious wearers.
-/obj/item/mod/control/proc/pai_fall()
- if(!wearer)
- return
- REMOVE_TRAIT(wearer, TRAIT_FORCED_STANDING, MOD_TRAIT)
-
/**
* Misc stuff to avoid having files with three lines in them.
*/
/obj/item/mod/control
- /// pAI mob inhabiting the MOD.
- var/mob/living/silicon/pai/mod_pai
/// Whether or not an on-board pAI can move the suit. FALSE by default, intended to be modified either via VV or via a possible future pAI program.
var/can_pai_move_suit = FALSE
-
-
-/datum/action/item_action/mod
- /// Whether this action is intended for the inserted pAI. Stuff breaks a lot if this is done differently.
- var/pai_action = FALSE
-
-
-/datum/action/item_action/mod/deploy/pai
- pai_action = TRUE
-
-
-/datum/action/item_action/mod/panel/pai
- pai_action = TRUE
-
-
-/datum/action/item_action/mod/module/pai
- pai_action = TRUE
-
-
-/datum/action/item_action/mod/activate/pai
- pai_action = TRUE
-
-
-/obj/item/mod/control/ui_state(mob/user)
- if(user == mod_pai)
- return GLOB.contained_state
- return ..()
+ /// Whether or not this MODsuit can hold AIs, or if it's restricted to just pAIs.
+ var/allow_ai = FALSE
diff --git a/tgui/packages/tgui/interfaces/MODsuit.tsx b/tgui/packages/tgui/interfaces/MODsuit.tsx
index ab3f69c1eda..6e737792447 100644
--- a/tgui/packages/tgui/interfaces/MODsuit.tsx
+++ b/tgui/packages/tgui/interfaces/MODsuit.tsx
@@ -33,8 +33,8 @@ type SuitStatus = {
complexity: number;
selected_module: string;
ai_name: string;
- pAI: string; // SKYRAT EDIT ADDITION - pAIs in MODsuits
- ispAI: BooleanLike; // SKYRAT EDIT ADDITION - pAIs in MODsuits
+ has_pai: boolean;
+ is_ai: boolean;
};
type UserStatus = {
@@ -315,8 +315,8 @@ const SuitStatusSection = (props, context) => {
malfunctioning,
locked,
ai_name,
- pAI,
- ispAI,
+ has_pai,
+ is_ai,
} = data.suit_status;
const { display_time, shift_time, shift_id } = data.module_custom_status;
const status = malfunctioning
@@ -388,20 +388,17 @@ const SuitStatusSection = (props, context) => {
)}
{!!ai_name && (
- {ai_name}
+
+ {has_pai && (
+
)}
- {/* SKYRAT EDIT START - pAIs in MODsuits*/}
-
- {pAI || 'None'}
- {!!pAI && !ispAI && (
-
- {/* SKYRAT EDIT END */}
{!!display_time && (
@@ -420,12 +417,12 @@ const SuitStatusSection = (props, context) => {
const HardwareSection = (props, context) => {
const { act, data } = useBackend(context);
const { control, helmet, chestplate, gauntlets, boots } = data;
- const { pAI, core_name } = data.suit_status; /* SKYRAT EDIT CHANGE - pAI */
+ const { ai_name, core_name } = data.suit_status;
return (
-
- {pAI || 'No pAI Card Detected' /* SKYRAT EDIT CHANGE - pAI */}
+
+ {ai_name || 'No AI Detected'}
{core_name || 'No Core Detected'}