mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 18:02:57 +00:00
Fix pAI shenanigans
This commit is contained in:
@@ -5,8 +5,6 @@
|
||||
var/obj/item/mod/control/mod
|
||||
/// Whether this action is intended for the AI. Stuff breaks a lot if this is done differently.
|
||||
var/ai_action = FALSE
|
||||
/// 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/New(Target)
|
||||
..()
|
||||
@@ -14,7 +12,7 @@
|
||||
qdel(src)
|
||||
return
|
||||
if(ai_action)
|
||||
background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND
|
||||
background_icon_state = "bg_tech"
|
||||
|
||||
/datum/action/item_action/mod/Grant(mob/user)
|
||||
mod = target
|
||||
@@ -53,9 +51,6 @@
|
||||
/datum/action/item_action/mod/deploy/ai
|
||||
ai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/deploy/pai
|
||||
pai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/activate
|
||||
name = "Activate MODsuit"
|
||||
desc = "Activate/Deactivate the MODsuit."
|
||||
@@ -70,9 +65,6 @@
|
||||
/datum/action/item_action/mod/activate/ai
|
||||
ai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/activate/pai
|
||||
pai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/module
|
||||
name = "Toggle Module"
|
||||
desc = "Toggle a MODsuit module."
|
||||
@@ -87,9 +79,6 @@
|
||||
/datum/action/item_action/mod/module/ai
|
||||
ai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/module/pai
|
||||
pai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/panel
|
||||
name = "MODsuit Panel"
|
||||
desc = "Open the MODsuit's panel."
|
||||
@@ -103,6 +92,3 @@
|
||||
|
||||
/datum/action/item_action/mod/panel/ai
|
||||
ai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/panel/pai
|
||||
pai_action = TRUE
|
||||
|
||||
@@ -122,6 +122,9 @@
|
||||
module.on_deactivation()
|
||||
activating = TRUE
|
||||
to_chat(wearer, span_notice("MODsuit [active ? "shutting down" : "starting up"]."))
|
||||
if(ai)
|
||||
to_chat(ai, span_notice("MODsuit [active ? "shutting down" : "starting up"]."))
|
||||
|
||||
if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE))
|
||||
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)
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
if(!ai)
|
||||
balloon_alert(user, "no AI in suit!")
|
||||
return
|
||||
if(!isAI(ai))
|
||||
balloon_alert(user, "onboard AI cannot fit in this card!")
|
||||
return
|
||||
balloon_alert(user, "transferring to card...")
|
||||
if(!do_after(user, 5 SECONDS, target = src))
|
||||
balloon_alert(user, "interrupted!")
|
||||
@@ -65,7 +68,7 @@
|
||||
ai = new_ai
|
||||
balloon_alert(new_ai, "transferred to a suit")
|
||||
for(var/datum/action/action as anything in actions)
|
||||
action.Grant(new_ai)
|
||||
action.Grant(ai)
|
||||
|
||||
/**
|
||||
* Simple proc to insert the pAI into the MODsuit.
|
||||
@@ -75,8 +78,8 @@
|
||||
*/
|
||||
|
||||
/obj/item/mod/control/proc/insert_pai(mob/user, obj/item/paicard/card)
|
||||
if(mod_pai)
|
||||
balloon_alert(user, "pAI already installed!")
|
||||
if(ai)
|
||||
balloon_alert(user, "AI already installed!")
|
||||
return
|
||||
if(!card.pai || !card.pai.mind)
|
||||
balloon_alert(user, "pAI unresponsive!")
|
||||
@@ -88,13 +91,13 @@
|
||||
if(!user.transferItemToLoc(card, src))
|
||||
return
|
||||
|
||||
mod_pai = card.pai
|
||||
card.pai.canholo = FALSE
|
||||
ai = card.pai
|
||||
balloon_alert(user, "pAI transferred to suit")
|
||||
balloon_alert(mod_pai, "transferred to a suit")
|
||||
mod_pai.canholo = FALSE
|
||||
mod_pai.remote_control = src
|
||||
balloon_alert(ai, "transferred to a suit")
|
||||
ai.remote_control = src
|
||||
for(var/datum/action/action as anything in actions)
|
||||
action.Grant(mod_pai)
|
||||
action.Grant(ai)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
@@ -106,10 +109,14 @@
|
||||
* 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(!ai)
|
||||
if(user && feedback)
|
||||
balloon_alert(user, "no pAI to remove!")
|
||||
return
|
||||
if(!ispAI(ai))
|
||||
if(user && feedback)
|
||||
balloon_alert(user, "onboard AI cannot fit in this card!")
|
||||
return
|
||||
if(!forced)
|
||||
if(!open)
|
||||
if(user && feedback)
|
||||
@@ -129,41 +136,48 @@
|
||||
* 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.
|
||||
* * feedback - Whether or not we want to give balloon alert feedback to the ai. Defaults to FALSE.
|
||||
*/
|
||||
/obj/item/mod/control/proc/remove_pai(feedback = FALSE)
|
||||
if(!ispAI(ai))
|
||||
return
|
||||
var/mob/living/silicon/pai/pai = ai
|
||||
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)
|
||||
pai.card.forceMove(drop_off)
|
||||
|
||||
for(var/datum/action/action as anything in actions)
|
||||
if(action.owner == mod_pai)
|
||||
action.Remove(mod_pai)
|
||||
if(action.owner == pai)
|
||||
action.Remove(pai)
|
||||
|
||||
if(feedback)
|
||||
balloon_alert(mod_pai, "removed from a suit")
|
||||
mod_pai.remote_control = null
|
||||
mod_pai.canholo = TRUE
|
||||
mod_pai = null
|
||||
balloon_alert(pai, "removed from a suit")
|
||||
pai.remote_control = null
|
||||
pai.canholo = TRUE
|
||||
pai = null
|
||||
|
||||
#define MOVE_DELAY 2
|
||||
#define WEARER_DELAY 1
|
||||
#define LONE_DELAY 5
|
||||
#define CELL_PER_STEP (DEFAULT_CHARGE_DRAIN * 2.5)
|
||||
#define AI_FALL_TIME (1 SECONDS)
|
||||
|
||||
/obj/item/mod/control/relaymove(mob/user, direction)
|
||||
if((!active && wearer) || !cell || cell.charge < CELL_PER_STEP || user != ai || !COOLDOWN_FINISHED(src, cooldown_mod_move) || (wearer?.pulledby?.grab_state > GRAB_PASSIVE))
|
||||
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)
|
||||
cell.charge = max(0, cell.charge - CELL_PER_STEP)
|
||||
if(ismovable(wearer?.loc))
|
||||
return wearer.loc.relaymove(wearer, direction)
|
||||
if(wearer && !wearer.Process_Spacemove(direction))
|
||||
return FALSE
|
||||
else if(!wearer && (!has_gravity() || !isturf(loc)))
|
||||
return FALSE
|
||||
COOLDOWN_START(src, cooldown_mod_move, movedelay * timemodifier + slowdown)
|
||||
cell.charge = max(0, cell.charge - CELL_PER_STEP)
|
||||
playsound(src, 'sound/mecha/mechmove01.ogg', 25, TRUE)
|
||||
if(ismovable(wearer?.loc))
|
||||
return wearer.loc.relaymove(wearer, direction)
|
||||
else if(wearer)
|
||||
ADD_TRAIT(wearer, TRAIT_MOBILITY_NOREST, MOD_TRAIT)
|
||||
addtimer(CALLBACK(src, .proc/ai_fall), AI_FALL_TIME, TIMER_UNIQUE | TIMER_OVERRIDE)
|
||||
var/atom/movable/mover = wearer || src
|
||||
return step(mover, direction)
|
||||
|
||||
@@ -171,8 +185,14 @@
|
||||
#undef WEARER_DELAY
|
||||
#undef LONE_DELAY
|
||||
#undef CELL_PER_STEP
|
||||
#undef AI_FALL_TIME
|
||||
|
||||
/obj/item/mod/control/proc/ai_fall()
|
||||
if(!wearer)
|
||||
return
|
||||
REMOVE_TRAIT(wearer, TRAIT_MOBILITY_NOREST, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/control/ui_state(mob/user)
|
||||
if(user == mod_pai)
|
||||
if(user == ai)
|
||||
return GLOB.contained_state
|
||||
return ..()
|
||||
|
||||
@@ -19,7 +19,16 @@
|
||||
strip_delay = 10 SECONDS
|
||||
slowdown = 2
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10)
|
||||
actions_types = list(/datum/action/item_action/mod/deploy, /datum/action/item_action/mod/activate, /datum/action/item_action/mod/module, /datum/action/item_action/mod/panel)
|
||||
actions_types = list(
|
||||
/datum/action/item_action/mod/deploy,
|
||||
/datum/action/item_action/mod/activate,
|
||||
/datum/action/item_action/mod/module,
|
||||
/datum/action/item_action/mod/panel,
|
||||
/datum/action/item_action/mod/deploy/ai,
|
||||
/datum/action/item_action/mod/activate/ai,
|
||||
/datum/action/item_action/mod/module/ai,
|
||||
/datum/action/item_action/mod/panel/ai,
|
||||
)
|
||||
resistance_flags = NONE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
@@ -74,10 +83,8 @@
|
||||
var/list/modules = list()
|
||||
/// Currently used module.
|
||||
var/obj/item/mod/module/selected_module
|
||||
/// AI mob inhabiting the MOD.
|
||||
var/mob/living/silicon/ai/ai
|
||||
/// pAI mob inhabiting the MOD.
|
||||
var/mob/living/silicon/pai/mod_pai
|
||||
/// AI/pAI mob inhabiting the MOD.
|
||||
var/mob/living/silicon/ai
|
||||
/// Delay between moves as AI.
|
||||
var/movedelay = 0
|
||||
/// Cooldown for AI moves.
|
||||
@@ -167,6 +174,7 @@
|
||||
for(var/obj/item/mod/module/module as anything in modules)
|
||||
module.mod = null
|
||||
modules -= module
|
||||
QDEL_NULL(ai)
|
||||
QDEL_NULL(wires)
|
||||
QDEL_NULL(cell)
|
||||
return ..()
|
||||
@@ -261,7 +269,8 @@
|
||||
. = ..()
|
||||
|
||||
/obj/item/mod/control/screwdriver_act(mob/living/user, obj/item/screwdriver)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(.)
|
||||
return TRUE
|
||||
if(active || activating)
|
||||
balloon_alert(user, "deactivate suit first!")
|
||||
@@ -307,6 +316,12 @@
|
||||
return FALSE
|
||||
|
||||
/obj/item/mod/control/attackby(obj/item/attacking_item, mob/living/user, params)
|
||||
if(istype(attacking_item, /obj/item/paicard))
|
||||
if(!open) //mod must be open
|
||||
balloon_alert(user, "suit must be open to transfer!")
|
||||
return FALSE
|
||||
insert_pai(user, attacking_item)
|
||||
return TRUE
|
||||
if(istype(attacking_item, /obj/item/mod/module))
|
||||
if(!open)
|
||||
balloon_alert(user, "open the panel first!")
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
ui = new(user, src, "MODsuit", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/mod/control/ui_data()
|
||||
/obj/item/mod/control/ui_data(mob/user)
|
||||
var/data = list()
|
||||
data["interface_break"] = interface_break
|
||||
data["malfunctioning"] = malfunctioning
|
||||
@@ -16,6 +16,8 @@
|
||||
data["wearer_name"] = wearer ? (wearer.get_authentification_name("Unknown") || "Unknown") : "No Occupant"
|
||||
data["wearer_job"] = wearer ? wearer.get_assignment("Unknown", "Unknown", FALSE) : "No Job"
|
||||
data["AI"] = ai?.name
|
||||
data["is_pAI"] = ai ? ispAI(ai) : FALSE
|
||||
data["is_user_AI"] = ai ? user == ai : FALSE
|
||||
data["cell"] = cell?.name
|
||||
data["charge"] = cell ? round(cell.percent(), 1) : 0
|
||||
data["modules"] = list()
|
||||
@@ -54,7 +56,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(locked && !allowed(usr))
|
||||
if((!allowed(usr) || !ispAI(usr)) && locked)
|
||||
balloon_alert(usr, "insufficient access!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return
|
||||
@@ -77,4 +79,8 @@
|
||||
if(!module)
|
||||
return
|
||||
module.configure_edit(params["key"], params["value"])
|
||||
if("remove_pai")
|
||||
if(ishuman(usr)) // Only the MODsuit's wearer should be removing the pAI.
|
||||
var/mob/user = usr
|
||||
extract_pai(user)
|
||||
return TRUE
|
||||
|
||||
@@ -467,6 +467,8 @@ const ParametersSection = (props, context) => {
|
||||
wearer_name,
|
||||
wearer_job,
|
||||
AI,
|
||||
is_pAI,
|
||||
is_user_AI,
|
||||
} = data;
|
||||
const status = malfunctioning
|
||||
? 'Malfunctioning'
|
||||
@@ -510,7 +512,21 @@ const ParametersSection = (props, context) => {
|
||||
<LabeledList.Item label="Occupant">
|
||||
{wearer_name}, {wearer_job}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Onboard AI">{AI || 'None'}</LabeledList.Item>
|
||||
<LabeledList.Item
|
||||
label="Onboard AI"
|
||||
buttons={
|
||||
AI && is_pAI && !is_user_AI ? (
|
||||
<Button
|
||||
icon="eject"
|
||||
content="Eject pAI"
|
||||
onClick={() => act('remove_pai')}
|
||||
/>
|
||||
) : (
|
||||
<> </>
|
||||
)
|
||||
}>
|
||||
{AI || 'None'}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user