Remote Mech Revision (#8903)

The AI can now remotely control mechs in its network. It has one mapped in near its core.
    Messages received by your old body will now reach your VR body (does not affect Skrell Srom).
    Exosuit pilots can now interact with elevator panels without having to get out.
    Robotics and RnD can now create remote controlled mechs. The control centre is in the protolathe, while the exosuit upgrade is in the circuit imprinter.
    Mechs can no longer be dismantled if it has a pilot in it.
    Dismantling a mech now takes a while.
This commit is contained in:
Geeves
2020-05-30 15:20:16 +02:00
committed by GitHub
parent aa39c8ca42
commit 19b1ddb869
37 changed files with 878 additions and 2937 deletions

View File

@@ -1625,6 +1625,7 @@
#include "code\modules\heavy_vehicle\components\frame.dm" #include "code\modules\heavy_vehicle\components\frame.dm"
#include "code\modules\heavy_vehicle\components\head.dm" #include "code\modules\heavy_vehicle\components\head.dm"
#include "code\modules\heavy_vehicle\components\legs.dm" #include "code\modules\heavy_vehicle\components\legs.dm"
#include "code\modules\heavy_vehicle\components\remote.dm"
#include "code\modules\heavy_vehicle\components\software.dm" #include "code\modules\heavy_vehicle\components\software.dm"
#include "code\modules\heavy_vehicle\equipment\_equipment.dm" #include "code\modules\heavy_vehicle\equipment\_equipment.dm"
#include "code\modules\heavy_vehicle\equipment\combat.dm" #include "code\modules\heavy_vehicle\equipment\combat.dm"
@@ -2465,6 +2466,7 @@
#include "code\modules\research\designs\circuit\exosuit_circuits.dm" #include "code\modules\research\designs\circuit\exosuit_circuits.dm"
#include "code\modules\research\designs\circuit\hardsuit_circuits.dm" #include "code\modules\research\designs\circuit\hardsuit_circuits.dm"
#include "code\modules\research\designs\circuit\machine_circuits.dm" #include "code\modules\research\designs\circuit\machine_circuits.dm"
#include "code\modules\research\designs\circuit\mecha_upgrades.dm"
#include "code\modules\research\designs\circuit\misc_electronics.dm" #include "code\modules\research\designs\circuit\misc_electronics.dm"
#include "code\modules\research\designs\circuit\shield_designs.dm" #include "code\modules\research\designs\circuit\shield_designs.dm"
#include "code\modules\research\designs\circuit\tcom_designs.dm" #include "code\modules\research\designs\circuit\tcom_designs.dm"
@@ -2475,6 +2477,7 @@
#include "code\modules\research\designs\mechfab\prosthetics\internal.dm" #include "code\modules\research\designs\mechfab\prosthetics\internal.dm"
#include "code\modules\research\designs\mechfab\robot\robot.dm" #include "code\modules\research\designs\mechfab\robot\robot.dm"
#include "code\modules\research\designs\mechfab\robot\robot_upgrades.dm" #include "code\modules\research\designs\mechfab\robot\robot_upgrades.dm"
#include "code\modules\research\designs\protolathe\deployable_kits.dm"
#include "code\modules\research\designs\protolathe\disk_designs.dm" #include "code\modules\research\designs\protolathe\disk_designs.dm"
#include "code\modules\research\designs\protolathe\hud_glasses_designs.dm" #include "code\modules\research\designs\protolathe\hud_glasses_designs.dm"
#include "code\modules\research\designs\protolathe\implant_designs.dm" #include "code\modules\research\designs\protolathe\implant_designs.dm"

View File

@@ -132,6 +132,7 @@
#define ui_ai_track_with_camera "SOUTH:6+1,WEST+2:16" #define ui_ai_track_with_camera "SOUTH:6+1,WEST+2:16"
#define ui_ai_camera_light "SOUTH:6+1,WEST+3:16" #define ui_ai_camera_light "SOUTH:6+1,WEST+3:16"
#define ui_ai_sensor "SOUTH:6+1,WEST+4:16" #define ui_ai_sensor "SOUTH:6+1,WEST+4:16"
#define ui_ai_mech "SOUTH:6+1,WEST+5:16"
#define ui_ai_core "SOUTH:6,WEST+1:16" #define ui_ai_core "SOUTH:6,WEST+1:16"
#define ui_ai_crew_monitor "SOUTH:6,WEST+2:16" #define ui_ai_crew_monitor "SOUTH:6,WEST+2:16"

View File

@@ -20,9 +20,10 @@
new /obj/screen/ai/take_image, new /obj/screen/ai/take_image,
new /obj/screen/ai/view_image, new /obj/screen/ai/view_image,
new /obj/screen/ai/sensor_aug, new /obj/screen/ai/sensor_aug,
new /obj/screen/ai/remote_mech,
new /obj/screen/ai/move_up, new /obj/screen/ai/move_up,
new /obj/screen/ai/move_down, new /obj/screen/ai/move_down,
myai.computer myai.computer
) )
mymob.client.screen += adding + other mymob.client.screen += adding + other

View File

@@ -180,6 +180,16 @@
var/mob/living/silicon/ai/AI = usr var/mob/living/silicon/ai/AI = usr
AI.sensor_mode() AI.sensor_mode()
/obj/screen/ai/remote_mech
name = "Remote Control Mech"
icon_state = "remote_mech"
screen_loc = ui_ai_mech
/obj/screen/ai/remote_mech/Click()
if(isAI(usr))
var/mob/living/silicon/ai/AI = usr
AI.remote_control_mech()
/obj/screen/ai/move_up /obj/screen/ai/move_up
name = "Move Up" name = "Move Up"
icon_state = "move_up" icon_state = "move_up"

View File

@@ -6,7 +6,7 @@
flags = SS_NO_FIRE flags = SS_NO_FIRE
// MECHA // MECHA
var/list/mechnetworks = list("remotemechs", "prisonmechs") // A list of all the networks a mech can possibly connect to var/list/mechnetworks = list("remotemechs", "aimechs", "prisonmechs") // A list of all the networks a mech can possibly connect to
var/list/list/mechs = list() // A list of lists, containing the mechs and their networks var/list/list/mechs = list() // A list of lists, containing the mechs and their networks
// IPC BODIES // IPC BODIES
@@ -41,35 +41,43 @@
robots[network].Remove(robot) robots[network].Remove(robot)
/mob/living/ /mob
var/mob/living/vr_mob = null // In which mob is our mind var/mob/living/vr_mob = null // In which mob is our mind
var/mob/living/old_mob = null // Which mob is our old mob var/mob/living/old_mob = null // Which mob is our old mob
// Return to our original body // Return to our original body
/mob/living/proc/body_return() /mob/proc/body_return()
set name = "Return to Body" set name = "Return to Body"
set category = "IC" set category = "IC"
if(!vr_mob && !old_mob)
return
if(vr_mob)
ckey = vr_mob.ckey
vr_mob.ckey = null
vr_mob.old_mob = null
vr_mob.languages = list(LANGUAGE_TCB)
vr_mob = null
to_chat(src, span("notice", "System exited safely, we hope you enjoyed your stay."))
if(old_mob) if(old_mob)
old_mob.ckey = ckey ckey_transfer(old_mob)
ckey = null languages = list(all_languages[LANGUAGE_TCB])
old_mob.vr_mob = null to_chat(old_mob, SPAN_NOTICE("System exited safely, we hope you enjoyed your stay."))
languages = list(LANGUAGE_TCB)
to_chat(old_mob, span("notice", "System exited safely, we hope you enjoyed your stay."))
old_mob = null old_mob = null
else else
to_chat(src, span("danger", "Interface error, you cannot exit the system at this time.")) to_chat(src, SPAN_DANGER("Interface error, you cannot exit the system at this time."))
to_chat(src, span("warning", "Ahelp to get back into your body, a bug has occurred.")) to_chat(src, SPAN_WARNING("Ahelp to get back into your body, a bug has occurred."))
/mob/living/silicon/body_return()
set name = "Return to Body"
set category = "IC"
if(old_mob)
ckey_transfer(old_mob)
speech_synthesizer_langs = list(all_languages[LANGUAGE_TCB])
to_chat(old_mob, SPAN_NOTICE("System exited safely, we hope you enjoyed your stay."))
old_mob = null
else
to_chat(src, SPAN_DANGER("Interface error, you cannot exit the system at this time."))
to_chat(src, SPAN_WARNING("Ahelp to get back into your body, a bug has occurred."))
/mob/living/proc/vr_mob_exit_languages()
languages = list(all_languages[LANGUAGE_TCB])
/mob/living/silicon/vr_mob_exit_languages()
..()
speech_synthesizer_langs = list(all_languages[LANGUAGE_TCB])
// Handles saving of the original mob and assigning the new mob // Handles saving of the original mob and assigning the new mob
/datum/controller/subsystem/virtualreality/proc/mind_transfer(var/mob/living/M, var/mob/living/target) /datum/controller/subsystem/virtualreality/proc/mind_transfer(var/mob/living/M, var/mob/living/target)
@@ -78,15 +86,41 @@
M.vr_mob = target M.vr_mob = target
target.ckey = new_ckey target.ckey = new_ckey
M.ckey = "@[new_ckey]" M.ckey = "@[new_ckey]"
target.verbs += /mob/living/proc/body_return target.verbs += /mob/proc/body_return
target.get_vr_name(M)
M.swap_languages(target)
target.languages = M.languages
if(target.client) if(target.client)
target.client.screen |= global_hud.vr_control target.client.screen |= global_hud.vr_control
to_chat(target, span("notice", "Connection established, system suite active and calibrated.")) to_chat(target, SPAN_NOTICE("Connection established, system suite active and calibrated."))
to_chat(target, span("warning", "To exit this mode, use the \"Return to Body\" verb in the IC tab.")) to_chat(target, SPAN_WARNING("To exit this mode, use the \"Return to Body\" verb in the IC tab."))
/mob/living/proc/swap_languages(var/mob/target)
target.languages = languages
if(issilicon(target))
var/mob/living/silicon/T = target
T.speech_synthesizer_langs = languages
/mob/living/silicon/swap_languages(mob/target)
target.languages = speech_synthesizer_langs
if(issilicon(target))
var/mob/living/silicon/T = target
T.speech_synthesizer_langs = speech_synthesizer_langs
/mob/proc/get_vr_name(var/mob/user)
return
/mob/living/simple_animal/spiderbot/get_vr_name(mob/user)
real_name = "Remote-Bot ([user.real_name])"
name = real_name
/mob/proc/ckey_transfer(var/mob/target, var/null_vr_mob = TRUE)
target.ckey = src.ckey
src.ckey = null
if(null_vr_mob)
target.vr_mob = null
/datum/controller/subsystem/virtualreality/proc/mech_selection(var/user, var/network) /datum/controller/subsystem/virtualreality/proc/mech_selection(var/user, var/network)
var/list/mech = list() var/list/mech = list()
@@ -107,10 +141,10 @@
continue continue
if(mech_pilot.stat == DEAD) if(mech_pilot.stat == DEAD)
continue continue
mech[mech_pilot.name] = mech_pilot mech[R.name] = R
if(mech.len == 1) if(mech.len == 1)
to_chat(user, span("warning", "No active remote mechs are available.")) to_chat(user, SPAN_WARNING("No active remote mechs are available."))
return return
var/desc = input("Please select a remote control compatible mech to take over.", "Remote Mech Selection") in mech|null var/desc = input("Please select a remote control compatible mech to take over.", "Remote Mech Selection") in mech|null
@@ -140,7 +174,7 @@
robot[R.name] = R robot[R.name] = R
if(robot.len == 1) if(robot.len == 1)
to_chat(user, span("warning", "No active remote robots are available.")) to_chat(user, SPAN_WARNING("No active remote robots are available."))
return return
var/desc = input("Please select a remote control robot to take over.", "Remote Robot Selection") in robot|null var/desc = input("Please select a remote control robot to take over.", "Remote Robot Selection") in robot|null

View File

@@ -236,6 +236,9 @@ var/obj/item/card/id/all_access/ghost_all_access
/mob/living/bot/GetIdCard() /mob/living/bot/GetIdCard()
return botcard return botcard
/mob/living/simple_animal/spiderbot/GetIdCard()
return internal_id
/mob/living/carbon/human/GetIdCard() /mob/living/carbon/human/GetIdCard()
if(wear_id) if(wear_id)
var/id = wear_id.GetID() var/id = wear_id.GetID()

View File

@@ -341,3 +341,17 @@ for reference:
w_class = 3 w_class = 3
kit_product = /obj/machinery/iv_drip kit_product = /obj/machinery/iv_drip
assembly_time = 4 SECONDS assembly_time = 4 SECONDS
/obj/item/deployable_kit/remote_mech
name = "mech control centre assembly kit"
desc = "A quick assembly kit to put together a mech control centre."
icon = 'icons/obj/storage.dmi'
icon_state = "barrier_kit"
w_class = ITEMSIZE_LARGE
kit_product = /obj/structure/bed/chair/remote/mech/portable
assembly_time = 20 SECONDS
/obj/item/deployable_kit/remote_mech/brig
name = "brig mech control centre assembly kit"
desc = "A quick assembly kit to put together a brig mech control centre."
kit_product = /obj/structure/bed/chair/remote/mech/prison/portable

View File

@@ -162,6 +162,13 @@
open() open()
return return
if(istype(AM, /mob/living/simple_animal/spiderbot))
var/mob/living/simple_animal/spiderbot/bot = AM
if(src.check_access(bot.internal_id))
if(density)
open()
return
if(istype(AM, /obj/structure/bed/chair/wheelchair)) if(istype(AM, /obj/structure/bed/chair/wheelchair))
var/obj/structure/bed/chair/wheelchair/wheel = AM var/obj/structure/bed/chair/wheelchair/wheel = AM
if(density) if(density)

View File

@@ -58,13 +58,20 @@
return ..() return ..()
/obj/machinery/door/window/CollidedWith(atom/movable/AM as mob|obj) /obj/machinery/door/window/CollidedWith(atom/movable/AM as mob|obj)
if (istype(AM, /obj)) if (istype(AM, /mob/living/bot))
var/mob/living/bot/bot = AM var/mob/living/bot/bot = AM
if(istype(bot)) if(istype(bot))
if(density && src.check_access(bot.botcard)) if(density && src.check_access(bot.botcard))
open() open()
addtimer(CALLBACK(src, .proc/close), 50) addtimer(CALLBACK(src, .proc/close), 50)
return return
if(istype(AM, /mob/living/simple_animal/spiderbot))
var/mob/living/simple_animal/spiderbot/bot = AM
if(istype(bot))
if(density && src.check_access(bot.internal_id))
open()
addtimer(CALLBACK(src, .proc/close), 50)
return
if (!( ROUND_IS_STARTED )) if (!( ROUND_IS_STARTED ))
return return
if (src.operating) if (src.operating)

View File

@@ -582,7 +582,9 @@
var/mob/living/heavy_vehicle/M = L var/mob/living/heavy_vehicle/M = L
if(!M.pilots?.len) if(!M.pilots?.len)
return TURRET_NOT_TARGET return TURRET_NOT_TARGET
for(var/mob/pilot in M.pilots)
if(allowed(pilot)) // don't shoot if the mech contains at least one person with access
return TURRET_NOT_TARGET
return TURRET_PRIORITY_TARGET //if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee return TURRET_PRIORITY_TARGET //if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee
/obj/machinery/porta_turret/proc/assess_perp(var/mob/living/carbon/human/H) /obj/machinery/porta_turret/proc/assess_perp(var/mob/living/carbon/human/H)

View File

@@ -55,16 +55,19 @@
/obj/proc/user_buckle_mob(mob/living/M, mob/user) /obj/proc/user_buckle_mob(mob/living/M, mob/user)
if(!ROUND_IS_STARTED) if(!ROUND_IS_STARTED)
to_chat(user, "<span class='warning'>You can't buckle anyone in before the game starts.</span>") to_chat(user, SPAN_WARNING("You can't buckle anyone in before the game starts."))
if(!user.Adjacent(M) || user.restrained() || user.stat || istype(user, /mob/living/silicon/pai)) if(!user.Adjacent(M) || user.restrained() || user.stat || istype(user, /mob/living/silicon/pai))
return return
if(!M.can_buckle)
to_chat(user, SPAN_WARNING("\The [M] can't be buckled!"))
return
if(M == buckled_mob) if(M == buckled_mob)
return return
if(istype(M, /mob/living/carbon/slime)) if(istype(M, /mob/living/carbon/slime))
to_chat(user, "<span class='warning'>The [M] is too squishy to buckle in.</span>") to_chat(user, SPAN_WARNING("\The [M] is too squishy to buckle in."))
return return
if (buckled_mob) if(buckled_mob)
to_chat(user, "<span class='warning'>[buckled_mob.name] is already there, unbuckle them first!.</span>") to_chat(user, SPAN_WARNING("\The [buckled_mob.name] is already there, unbuckle them first!."))
return return
add_fingerprint(user) add_fingerprint(user)

View File

@@ -2,12 +2,34 @@
name = "virtual reality centre" name = "virtual reality centre"
desc = "A comfortable chair with full audio-visual transposition centres." desc = "A comfortable chair with full audio-visual transposition centres."
icon_state = "shuttlechair_down" icon_state = "shuttlechair_down"
var/portable = FALSE // can it be moved around 'n shit
var/portable_type
can_dismantle = FALSE can_dismantle = FALSE
var/list/remote_network // Which network does this remote control belong to? var/list/remote_network // Which network does this remote control belong to?
/obj/structure/bed/chair/remote/Initialize()
. = ..()
if(portable && portable_type)
name = "portable [name]"
/obj/structure/bed/chair/remote/examine(mob/user)
..()
if(portable && portable_type)
to_chat(user, FONT_SMALL(SPAN_NOTICE("Can be packed up by using a wrench on it.")))
/obj/structure/bed/chair/remote/update_icon() /obj/structure/bed/chair/remote/update_icon()
return return
/obj/structure/bed/chair/remote/attackby(obj/item/W, mob/user)
if(portable && portable_type && W.iswrench())
user.visible_message(SPAN_NOTICE("\The [user] starts dismantling \the [src]..."), SPAN_NOTICE("You start dismantling \the [src]..."))
if(do_after(user, 20 SECONDS, TRUE, src))
user.visible_message(SPAN_NOTICE("\The [user] dismantles \the [src]."), SPAN_NOTICE("You dismantle \the [src]."))
var/obj/kit = new portable_type(get_turf(src))
user.put_in_hands(kit)
return
..()
/obj/structure/bed/chair/remote/user_buckle_mob(mob/user) /obj/structure/bed/chair/remote/user_buckle_mob(mob/user)
..() ..()
if(ishuman(user)) if(ishuman(user))
@@ -19,8 +41,9 @@
// Return to our body in the unfortunate event that we get unbuckled while plugged in // Return to our body in the unfortunate event that we get unbuckled while plugged in
/obj/structure/bed/chair/remote/user_unbuckle_mob(mob/user) /obj/structure/bed/chair/remote/user_unbuckle_mob(mob/user)
if(ishuman(user)) if(buckled_mob)
var/mob/living/carbon/human/H = user var/mob/M = buckled_mob
H.body_return() if(istype(M) && M.vr_mob)
cut_overlays() M.vr_mob.body_return()
cut_overlays()
..() ..()

View File

@@ -9,7 +9,15 @@
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
SSvirtualreality.mech_selection(H, remote_network) SSvirtualreality.mech_selection(H, remote_network)
/obj/structure/bed/chair/remote/mech/portable
portable = TRUE
portable_type = /obj/item/deployable_kit/remote_mech
/obj/structure/bed/chair/remote/mech/prison /obj/structure/bed/chair/remote/mech/prison
name = "brig mech control centre" name = "brig mech control centre"
desc = "A comfortable chair with full audio-visual transposition centres. This one gives you access to exosuits attached to the brig network." desc = "A comfortable chair with full audio-visual transposition centres. This one gives you access to exosuits attached to the brig network."
remote_network = "prisonmechs" remote_network = "prisonmechs"
/obj/structure/bed/chair/remote/mech/prison/portable
portable = TRUE
portable_type = /obj/item/deployable_kit/remote_mech/brig

View File

@@ -0,0 +1,34 @@
/obj/item/remote_mecha
name = "standard exosuit remote upgrade"
desc = "A device that, when inserted into an exosuit, allows it to be remotely piloted."
icon = 'icons/obj/modular_components.dmi'
icon_state = "aislot"
origin_tech = list(TECH_BLUESPACE = 3, TECH_MATERIAL = 4, TECH_DATA = 4)
w_class = ITEMSIZE_SMALL
var/mech_remote_network = "remotemechs"
var/hardpoint_lock = FALSE // Whether mechs that receive this upgrade gets locked
var/dummy_path = /mob/living/simple_animal/spiderbot
/obj/item/remote_mecha/examine(mob/user)
. = ..()
to_chat(user, FONT_SMALL(SPAN_WARNING("This exosuit upgrade cannot be undone if applied!")))
if(Adjacent(user))
var/message = "Applying \the [src] <b>will [hardpoint_lock ? "" : "not"]</b> lock the hardpoints[hardpoint_lock ? ", preventing further modification" : ""]."
to_chat(user, FONT_SMALL(SPAN_NOTICE(message)))
/obj/item/remote_mecha/penal
name = "penal exosuit remote upgrade"
desc = "A device that, when inserted into an exosuit, allows it to be remotely piloted. Intended for prison networks."
mech_remote_network = "prisonmechs"
hardpoint_lock = TRUE
/obj/item/remote_mecha/penal/examine(mob/user)
. = ..()
if(Adjacent(user))
to_chat(user, FONT_SMALL(SPAN_NOTICE("Applying \the [src] will additionally add the mech to the security penal network, where they can remotely monitor and shut it down.")))
/obj/item/remote_mecha/ai
name = "AI exosuit remote upgrade"
desc = "A device that, when inserted into an exosuit, allows it to be remotely piloted by the artificial intelligence."
mech_remote_network = "aimechs"
dummy_path = /mob/living/simple_animal/spiderbot/ai

View File

@@ -346,7 +346,29 @@
else else
if(user.a_intent != I_HURT) if(user.a_intent != I_HURT)
if(thing.ismultitool()) if(istype(thing, /obj/item/remote_mecha))
if(length(pilots))
to_chat(user, SPAN_WARNING("You can't apply this upgrade while \the [src] has occupants!"))
return
if(!maintenance_protocols)
to_chat(user, SPAN_WARNING("You are unable to apply this upgrade while \the [src]'s maintenance protocols are not active."))
return
user.visible_message(SPAN_NOTICE("\The [user] begins installing \the [thing] into \the [src]..."), SPAN_NOTICE("You begin installing the [thing] into \the [src]..."))
if(do_after(user, 30, TRUE, src))
if(length(pilots))
to_chat(user, SPAN_WARNING("You can't apply this upgrade while \the [src] has occupants!"))
return
if(!maintenance_protocols)
to_chat(user, SPAN_WARNING("You are unable to apply this upgrade while \the [src]'s maintenance protocols are not active."))
return
var/obj/item/remote_mecha/RM = thing
user.visible_message(SPAN_NOTICE("\The [user] installs \the [thing] into \the [src]."), SPAN_NOTICE("You install the [thing] into \the [src]."))
remote_network = RM.mech_remote_network
does_hardpoint_lock = RM.hardpoint_lock
dummy_type = RM.dummy_path
become_remote()
qdel(thing)
else if(thing.ismultitool())
if(hardpoints_locked) if(hardpoints_locked)
to_chat(user, "<span class='warning'>Hardpoint system access is disabled.</span>") to_chat(user, "<span class='warning'>Hardpoint system access is disabled.</span>")
return return
@@ -364,12 +386,23 @@
return return
else if(thing.iswrench()) else if(thing.iswrench())
if(!maintenance_protocols) if(length(pilots))
to_chat(user, "<span class='warning'>The securing bolts are not visible while maintenance protocols are disabled.</span>") to_chat(user, SPAN_WARNING("You can't disassemble \the [src] while it has a pilot!"))
return
if(!maintenance_protocols)
to_chat(user, SPAN_WARNING("The securing bolts are not visible while maintenance protocols are disabled."))
return
user.visible_message(SPAN_NOTICE("\The [user] starts dismantling \the [src]..."), SPAN_NOTICE("You start disassembling \the [src]..."))
if(do_after(user, 30, TRUE, src))
if(length(pilots))
to_chat(user, SPAN_WARNING("You can't disassemble \the [src] while it has a pilot!"))
return
if(!maintenance_protocols)
to_chat(user, SPAN_WARNING("The securing bolts are not visible while maintenance protocols are disabled."))
return
user.visible_message(SPAN_NOTICE("\The [user] dismantles \the [src]."), SPAN_NOTICE("You disassemble \the [src]."))
dismantle()
return return
to_chat(user, "<span class='notice'>You dismantle \the [src].</span>")
dismantle()
return
else if(thing.iswelder()) else if(thing.iswelder())
if(!getBruteLoss()) if(!getBruteLoss())
return return

View File

@@ -1,13 +1,14 @@
// Big stompy robots. // Big stompy robots.
/mob/living/heavy_vehicle /mob/living/heavy_vehicle
name = "exosuit" name = "exosuit"
density = 1 density = TRUE
opacity = 1 opacity = TRUE
anchored = 1 anchored = TRUE
status_flags = PASSEMOTES status_flags = PASSEMOTES
a_intent = I_HURT a_intent = I_HURT
mob_size = MOB_LARGE mob_size = MOB_LARGE
mob_push_flags = ALLMOBS mob_push_flags = ALLMOBS
can_buckle = FALSE
var/decal var/decal
var/emp_damage = 0 var/emp_damage = 0
@@ -24,7 +25,7 @@
// Access updating/container. // Access updating/container.
var/obj/item/card/id/access_card var/obj/item/card/id/access_card
var/list/saved_access = list() var/list/saved_access = list()
var/sync_access = 1 var/sync_access = TRUE
// Mob currently piloting the mech. // Mob currently piloting the mech.
var/list/pilots var/list/pilots
@@ -32,7 +33,9 @@
// Remote control stuff // Remote control stuff
var/remote = FALSE // Spawns a robotic pilot to be remote controlled var/remote = FALSE // Spawns a robotic pilot to be remote controlled
var/mob/living/carbon/human/industrial_xion_remote_mech/dummy // The remote controlled dummy var/does_hardpoint_lock = TRUE
var/mob/living/simple_animal/spiderbot/dummy // The remote controlled dummy
var/dummy_type = /mob/living/simple_animal/spiderbot
var/dummy_colour var/dummy_colour
// Visible external components. Not strictly accurately named for non-humanoid machines (submarines) but w/e // Visible external components. Not strictly accurately named for non-humanoid machines (submarines) but w/e
@@ -56,8 +59,8 @@
var/material/material var/material/material
// Cockpit access vars. // Cockpit access vars.
var/hatch_closed = 0 var/hatch_closed = FALSE
var/hatch_locked = 0 var/hatch_locked = FALSE
var/force_locked = FALSE // Is it possible to unlock the hatch? var/force_locked = FALSE // Is it possible to unlock the hatch?
var/use_air = FALSE var/use_air = FALSE
@@ -241,16 +244,20 @@
remote = TRUE remote = TRUE
name = name + " \"[pick("Jaeger", "Reaver", "Templar", "Juggernaut", "Basilisk")]-[rand(0, 999)]\"" name = name + " \"[pick("Jaeger", "Reaver", "Templar", "Juggernaut", "Basilisk")]-[rand(0, 999)]\""
if(remote_network) if(!remote_network)
SSvirtualreality.add_mech(src, remote_network)
else
remote_network = "remotemechs" remote_network = "remotemechs"
SSvirtualreality.add_mech(src, remote_network) SSvirtualreality.add_mech(src, remote_network)
if(hatch_closed) if(hatch_closed)
hatch_closed = FALSE hatch_closed = FALSE
dummy = new /mob/living/carbon/human/industrial_xion_remote_mech(get_turf(src)) dummy = new dummy_type(get_turf(src))
dummy.real_name = "Remote-Bot"
dummy.name = dummy.real_name
dummy.mmi = new /obj/item/device/mmi(dummy) // this is literally just because i luck the aesthetics - geeves
dummy.verbs -= /mob/living/proc/ventcrawl
dummy.verbs -= /mob/living/proc/hide
dummy.update_icon()
if(dummy_colour) if(dummy_colour)
dummy.color = dummy_colour dummy.color = dummy_colour
enter(dummy, TRUE) enter(dummy, TRUE)
@@ -258,5 +265,7 @@
if(!hatch_closed) if(!hatch_closed)
hatch_closed = TRUE hatch_closed = TRUE
hatch_locked = TRUE hatch_locked = TRUE
hardpoints_locked = TRUE if(does_hardpoint_lock)
force_locked = TRUE hardpoints_locked = TRUE
force_locked = TRUE
update_icon()

View File

@@ -19,6 +19,7 @@
name = "remote mining mecha" name = "remote mining mecha"
dummy_colour = "#ffc44f" dummy_colour = "#ffc44f"
remote_network = "remotemechs" remote_network = "remotemechs"
does_hardpoint_lock = FALSE
/mob/living/heavy_vehicle/premade/miner/remote_prison /mob/living/heavy_vehicle/premade/miner/remote_prison
name = "penal mining mecha" name = "penal mining mecha"

View File

@@ -152,8 +152,17 @@
name = "remote power loader" name = "remote power loader"
dummy_colour = "#ffc44f" dummy_colour = "#ffc44f"
remote_network = "remotemechs" remote_network = "remotemechs"
does_hardpoint_lock = FALSE
/mob/living/heavy_vehicle/premade/ripley/remote_prison /mob/living/heavy_vehicle/premade/ripley/remote_prison
name = "penal power loader" name = "penal power loader"
dummy_colour = "#302e2b" dummy_colour = "#302e2b"
remote_network = "prisonmechs" remote_network = "prisonmechs"
/mob/living/heavy_vehicle/premade/ripley/remote_ai
name = "stationbound power loader"
e_color = COLOR_GREEN_GRAY
dummy_colour = COLOR_GREEN_GRAY
dummy_type = /mob/living/simple_animal/spiderbot/ai
remote_network = "aimechs"
does_hardpoint_lock = FALSE

View File

@@ -58,6 +58,12 @@
if(!gibbed && deathmessage != "no message") // This is gross, but reliable. Only brains use it. if(!gibbed && deathmessage != "no message") // This is gross, but reliable. Only brains use it.
src.visible_message("<b>\The [src.name]</b> [deathmessage]", range = messagerange) src.visible_message("<b>\The [src.name]</b> [deathmessage]", range = messagerange)
// If we have a remotely controlled mob, we come back to our body to die properly
if(vr_mob)
vr_mob.body_return()
// Alternatively, if we are the remotely controlled mob, just kick our controller out
if(old_mob)
body_return()
stat = DEAD stat = DEAD
update_canmove() update_canmove()

View File

@@ -1,7 +1,7 @@
// At minimum every mob has a hear_say proc. // At minimum every mob has a hear_say proc.
/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol) /mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
if(!istype(src, /mob/living/test) && !client) if(!istype(src, /mob/living/test) && (!client && !vr_mob))
return return
if(speaker && !istype(speaker, /mob/living/test) && (!speaker.client && istype(src,/mob/abstract/observer) && client.prefs.toggles & CHAT_GHOSTEARS && !(speaker in view(src)))) if(speaker && !istype(speaker, /mob/living/test) && (!speaker.client && istype(src,/mob/abstract/observer) && client.prefs.toggles & CHAT_GHOSTEARS && !(speaker in view(src))))
@@ -21,7 +21,7 @@
italics = 1 italics = 1
sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact
if(sleeping || stat == 1) if((sleeping && !vr_mob) || stat == 1)
hear_sleep(message) hear_sleep(message)
return return
@@ -82,17 +82,20 @@
/mob/proc/on_hear_say(var/message) /mob/proc/on_hear_say(var/message)
to_chat(src, message) to_chat(src, message)
if(vr_mob)
to_chat(vr_mob, message)
/mob/living/silicon/on_hear_say(var/message) /mob/living/silicon/on_hear_say(var/message)
var/time = say_timestamp() var/time = say_timestamp()
to_chat(src, "[time] [message]") to_chat(src, "[time] [message]")
if(vr_mob)
to_chat(vr_mob, "[time] [message]")
/mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="") /mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="")
if(!client && !vr_mob)
if(!client)
return return
if(sleeping || stat==1) //If unconscious or sleeping if((sleeping && !vr_mob) || stat==1) //If unconscious or sleeping
hear_sleep(message) hear_sleep(message)
return return
@@ -209,6 +212,8 @@
/mob/proc/on_hear_radio(part_a, speaker_name, track, part_b, formatted) /mob/proc/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
to_chat(src, "[part_a][speaker_name][part_b][formatted]") to_chat(src, "[part_a][speaker_name][part_b][formatted]")
if(vr_mob)
to_chat(vr_mob, "[part_a][speaker_name][part_b][formatted]")
/mob/abstract/observer/on_hear_radio(part_a, speaker_name, track, part_b, formatted) /mob/abstract/observer/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
to_chat(src, "[track][part_a][speaker_name][part_b][formatted]") to_chat(src, "[track][part_a][speaker_name][part_b][formatted]")
@@ -216,10 +221,14 @@
/mob/living/silicon/on_hear_radio(part_a, speaker_name, track, part_b, formatted) /mob/living/silicon/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
var/time = say_timestamp() var/time = say_timestamp()
to_chat(src, "[time][part_a][speaker_name][part_b][formatted]") to_chat(src, "[time][part_a][speaker_name][part_b][formatted]")
if(vr_mob)
to_chat(vr_mob, "[time][part_a][speaker_name][part_b][formatted]")
/mob/living/silicon/ai/on_hear_radio(part_a, speaker_name, track, part_b, formatted) /mob/living/silicon/ai/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
var/time = say_timestamp() var/time = say_timestamp()
to_chat(src, "[time][part_a][track][part_b][formatted]") to_chat(src, "[time][part_a][track][part_b][formatted]")
if(vr_mob)
to_chat(vr_mob, "[time][part_a][track][part_b][formatted]")
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null) /mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null)
if(!client || !speaker) if(!client || !speaker)

View File

@@ -108,7 +108,7 @@
if(H && show_ssd && !client && !teleop) if(H && show_ssd && !client && !teleop)
if(H.bg) if(H.bg)
to_chat(H, span("danger", "You sense some disturbance to your physical body!")) to_chat(H, span("danger", "You sense some disturbance to your physical body!"))
else else if(!vr_mob)
visible_message(span("notice", "[M] [action] [src], but they do not respond... Maybe they have S.S.D?")) visible_message(span("notice", "[M] [action] [src], but they do not respond... Maybe they have S.S.D?"))
else if(client && willfully_sleeping) else if(client && willfully_sleeping)
visible_message(span("notice", "[M] [action] [src] waking [t_him] up!")) visible_message(span("notice", "[M] [action] [src] waking [t_him] up!"))
@@ -271,7 +271,7 @@
if(H && show_ssd && !client && !teleop) if(H && show_ssd && !client && !teleop)
if(H.bg) if(H.bg)
to_chat(H, span("warning", "You sense some disturbance to your physical body, like someone is trying to wake you up.")) to_chat(H, span("warning", "You sense some disturbance to your physical body, like someone is trying to wake you up."))
else else if(!vr_mob)
M.visible_message(span("notice", "[M] shakes [src] trying to wake [t_him] up!"), \ M.visible_message(span("notice", "[M] shakes [src] trying to wake [t_him] up!"), \
span("notice", "You shake [src], but they do not respond... Maybe they have S.S.D?")) span("notice", "You shake [src], but they do not respond... Maybe they have S.S.D?"))
else if(lying) else if(lying)

View File

@@ -26,7 +26,7 @@
willfully_sleeping = FALSE willfully_sleeping = FALSE
else else
to_chat(H, span("danger", "You sense great disturbance to your physical body!")) to_chat(H, span("danger", "You sense great disturbance to your physical body!"))
else else if(!vr_mob)
visible_message(span("danger","[src] is hit by [AM], but they do not respond... Maybe they have S.S.D?")) visible_message(span("danger","[src] is hit by [AM], but they do not respond... Maybe they have S.S.D?"))
else if(client && willfully_sleeping) else if(client && willfully_sleeping)
visible_message(span("danger", "[src] is hit by [AM] waking [t_him] up!")) visible_message(span("danger", "[src] is hit by [AM] waking [t_him] up!"))
@@ -54,7 +54,7 @@
willfully_sleeping = FALSE willfully_sleeping = FALSE
else else
to_chat(H, span("danger", "You sense great disturbance to your physical body!")) to_chat(H, span("danger", "You sense great disturbance to your physical body!"))
else else if(!vr_mob)
visible_message("<span class='danger'>[P] hit [src], but they do not respond... Maybe they have S.S.D?</span>") visible_message("<span class='danger'>[P] hit [src], but they do not respond... Maybe they have S.S.D?</span>")
else if(client && willfully_sleeping) else if(client && willfully_sleeping)
visible_message("<span class='danger'>[P] hit [src] waking [t_him] up!</span>") visible_message("<span class='danger'>[P] hit [src] waking [t_him] up!</span>")
@@ -80,7 +80,7 @@
willfully_sleeping = FALSE willfully_sleeping = FALSE
else else
to_chat(H, span("danger", "You sense great disturbance to your physical body!")) to_chat(H, span("danger", "You sense great disturbance to your physical body!"))
else else if(!vr_mob)
user.visible_message("<span class='danger'>[user] attacks [src] with [I] waking [t_him] up!</span>", \ user.visible_message("<span class='danger'>[user] attacks [src] with [I] waking [t_him] up!</span>", \
"<span class='danger'>You attack [src] with [I], but they do not respond... Maybe they have S.S.D?</span>") "<span class='danger'>You attack [src] with [I], but they do not respond... Maybe they have S.S.D?</span>")
else if(client && willfully_sleeping) else if(client && willfully_sleeping)

View File

@@ -114,11 +114,6 @@
return return
/mob/living/carbon/human/proc/vr_disconnect() /mob/living/carbon/human/proc/vr_disconnect()
// Come out of VR right before you die, how depressing - geeves
// Also come out of VR if your VR body dies
if(vr_mob || old_mob)
body_return()
if(remote_network) if(remote_network)
SSvirtualreality.remove_robot(src, remote_network) SSvirtualreality.remove_robot(src, remote_network)
remote_network = null remote_network = null

View File

@@ -324,7 +324,7 @@
if(H && show_ssd && !H.client && !H.teleop) if(H && show_ssd && !H.client && !H.teleop)
if(H.bg) if(H.bg)
to_chat(H, span("danger", "You sense some disturbance to your physical body!")) to_chat(H, span("danger", "You sense some disturbance to your physical body!"))
else else if(!vr_mob)
message = "<span class='danger'>slaps [M] across the face, but they do not respond... Maybe they have S.S.D?</span>" message = "<span class='danger'>slaps [M] across the face, but they do not respond... Maybe they have S.S.D?</span>"
else if(H.client && H.willfully_sleeping) else if(H.client && H.willfully_sleeping)
message = "<span class='danger'>slaps [M] across the face, waking them up. Ouch!</span>" message = "<span class='danger'>slaps [M] across the face, waking them up. Ouch!</span>"

View File

@@ -262,9 +262,9 @@
if(species.show_ssd && (!species.has_organ[BP_BRAIN] || has_brain()) && stat != DEAD) if(species.show_ssd && (!species.has_organ[BP_BRAIN] || has_brain()) && stat != DEAD)
if(!key) if(!vr_mob && !key)
msg += "<span class='deadsay'>[T.He] [T.is] [species.show_ssd]. It doesn't look like [T.he] [T.is] waking up anytime soon.</span>\n" msg += "<span class='deadsay'>[T.He] [T.is] [species.show_ssd]. It doesn't look like [T.he] [T.is] waking up anytime soon.</span>\n"
else if(!client && !bg) else if(!vr_mob && !client && !bg)
msg += "<span class='deadsay'>[T.He] [T.is] [species.show_ssd].</span>\n" msg += "<span class='deadsay'>[T.He] [T.is] [species.show_ssd].</span>\n"
if(have_client && ((inactivity / 600) > 10)) // inactivity/10/60 > 10 MINUTES if(have_client && ((inactivity / 600) > 10)) // inactivity/10/60 > 10 MINUTES
msg += "<span class='deadsay'>\[Inactive for [round(inactivity / 600)] minutes.\]\n</span>" msg += "<span class='deadsay'>\[Inactive for [round(inactivity / 600)] minutes.\]\n</span>"

View File

@@ -721,7 +721,7 @@
return 0 return 0
//SSD check, if a logged player is awake put them back to sleep! //SSD check, if a logged player is awake put them back to sleep!
if(species.show_ssd && !client && !teleop) if(species.show_ssd && (!client && !vr_mob) && !teleop)
Sleeping(2) Sleeping(2)
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
blinded = 1 blinded = 1

View File

@@ -20,6 +20,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/core, /mob/living/silicon/ai/proc/core,
/mob/living/silicon/ai/proc/pick_icon, /mob/living/silicon/ai/proc/pick_icon,
/mob/living/silicon/ai/proc/sensor_mode, /mob/living/silicon/ai/proc/sensor_mode,
/mob/living/silicon/ai/proc/remote_control_mech,
/mob/living/silicon/ai/proc/show_laws_verb, /mob/living/silicon/ai/proc/show_laws_verb,
/mob/living/silicon/ai/proc/toggle_acceleration, /mob/living/silicon/ai/proc/toggle_acceleration,
/mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/toggle_camera_light,
@@ -310,6 +311,7 @@ var/list/ai_verbs_default = list(
if(id_card) if(id_card)
id_card.registered_name = pickedName id_card.registered_name = pickedName
id_card.assignment = "AI" id_card.assignment = "AI"
id_card.access = get_all_station_access()
id_card.update_name() id_card.update_name()
if(client) if(client)
@@ -772,6 +774,12 @@ var/list/ai_verbs_default = list(
set desc = "Augment visual feed with internal sensor overlays" set desc = "Augment visual feed with internal sensor overlays"
toggle_sensor_mode() toggle_sensor_mode()
/mob/living/silicon/ai/proc/remote_control_mech()
set name = "Remote Control Mech"
set category = "AI Commands"
set desc = "Remotely control any active mechs on your AI mech network."
SSvirtualreality.mech_selection(src, "aimechs")
/mob/living/silicon/ai/proc/toggle_hologram_movement() /mob/living/silicon/ai/proc/toggle_hologram_movement()
set name = "Toggle Hologram Movement" set name = "Toggle Hologram Movement"
set category = "AI Commands" set category = "AI Commands"

View File

@@ -16,4 +16,5 @@
card.update_icon() card.update_icon()
. = ..(gibbed,"gives one shrill beep before falling lifeless.") . = ..(gibbed,"gives one shrill beep before falling lifeless.")
density = 1 density = TRUE
ghostize(FALSE)

View File

@@ -12,6 +12,7 @@
var/obj/item/cell/cell = null var/obj/item/cell/cell = null
var/obj/machinery/camera/camera = null var/obj/machinery/camera/camera = null
var/obj/item/device/mmi/mmi = null var/obj/item/device/mmi/mmi = null
var/obj/item/card/id/internal_id = null
var/list/req_access = list(access_robotics) //Access needed to pop out the brain. var/list/req_access = list(access_robotics) //Access needed to pop out the brain.
var/positronic var/positronic
@@ -44,8 +45,9 @@
/mob/living/simple_animal/spiderbot/Initialize() /mob/living/simple_animal/spiderbot/Initialize()
. = ..() . = ..()
add_language("Ceti Basic") add_language(LANGUAGE_TCB)
default_language = all_languages["Ceti Basic"] default_language = all_languages[LANGUAGE_TCB]
internal_id = new /obj/item/card/id(src)
verbs |= /mob/living/proc/ventcrawl verbs |= /mob/living/proc/ventcrawl
verbs |= /mob/living/proc/hide verbs |= /mob/living/proc/hide
@@ -302,3 +304,7 @@
/mob/living/simple_animal/spiderbot/get_bullet_impact_effect_type(var/def_zone) /mob/living/simple_animal/spiderbot/get_bullet_impact_effect_type(var/def_zone)
return BULLET_IMPACT_METAL return BULLET_IMPACT_METAL
/mob/living/simple_animal/spiderbot/ai/Initialize()
. = ..()
internal_id.access = get_all_station_access()

View File

@@ -7,6 +7,7 @@
var/datum/mind/mind var/datum/mind/mind
var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
var/can_buckle = TRUE
var/obj/screen/flash = null var/obj/screen/flash = null
var/obj/screen/blind = null var/obj/screen/blind = null

View File

@@ -62,6 +62,16 @@
/atom/proc/contents_nano_distance(var/src_object, var/mob/living/user) /atom/proc/contents_nano_distance(var/src_object, var/mob/living/user)
return user.shared_living_nano_distance(src_object) return user.shared_living_nano_distance(src_object)
/mob/living/heavy_vehicle/contents_nano_distance(src_object, mob/living/user)
if(src_object in contents)
return STATUS_INTERACTIVE
if(hatch_closed && body.pilot_coverage == 100 && !istype(user, /mob/living/simple_animal/spiderbot)) // spiderbots get a pass cuz they need a bone, call it RFID bullshit
to_chat(user, SPAN_WARNING("You can't interact with things outside \the [src] if its hatch is closed!"))
return STATUS_CLOSE
if(!src.Adjacent(src_object))
return STATUS_CLOSE
return STATUS_INTERACTIVE
/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object) /mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object)
if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates
return STATUS_CLOSE return STATUS_CLOSE
@@ -79,7 +89,10 @@
. = shared_nano_interaction(src_object) . = shared_nano_interaction(src_object)
if(. != STATUS_CLOSE) if(. != STATUS_CLOSE)
if(loc) if(loc)
. = min(., loc.contents_nano_distance(src_object, src)) if(istype(loc, /mob/living/heavy_vehicle))
return loc.contents_nano_distance(src_object, src)
else
. = min(., loc.contents_nano_distance(src_object, src))
if(. == STATUS_INTERACTIVE) if(. == STATUS_INTERACTIVE)
return STATUS_UPDATE return STATUS_UPDATE
@@ -87,6 +100,9 @@
. = shared_nano_interaction(src_object) . = shared_nano_interaction(src_object)
if(. != STATUS_CLOSE) if(. != STATUS_CLOSE)
if(loc) if(loc)
. = min(., loc.contents_nano_distance(src_object, src)) if(istype(loc, /mob/living/heavy_vehicle))
. = loc.contents_nano_distance(src_object, src)
else
. = min(., loc.contents_nano_distance(src_object, src))
else else
. = min(., shared_living_nano_distance(src_object)) . = min(., shared_living_nano_distance(src_object))

View File

@@ -0,0 +1,22 @@
/datum/design/circuit/exosuit_upgrade
design_order = 2.6
/datum/design/circuit/exosuit_upgrade/AssembleDesignName()
name = "Exosuit Hardware Upgrade ([name])"
/datum/design/circuit/exosuit/AssembleDesignDesc()
desc = "Complex circuitry which unlock certain exosuit faculties."
/datum/design/circuit/exosuit_upgrade/remote
name = "Standard Remote Control"
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4, TECH_MATERIAL = 4)
build_path = /obj/item/remote_mecha
/datum/design/circuit/exosuit_upgrade/remote/penal
name = "Penal Remote Control"
build_path = /obj/item/remote_mecha/penal
/datum/design/circuit/exosuit_upgrade/remote/ai
name = "AI Remote Control"
req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 4, TECH_MATERIAL = 4)
build_path = /obj/item/remote_mecha/ai

View File

@@ -0,0 +1,17 @@
/datum/design/item/deployable_kit
design_order = 11
/datum/design/item/deployable_kit/AssembleDesignName()
name = "Deployable Kit Design ([name])"
/datum/design/item/deployable_kit/mech_chair
name = "Remote Mech Centre"
desc = "A deployable kit of a remote mech chair, capable of listening in to standard remote mech networks."
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4, TECH_MATERIAL = 4)
materials = list(DEFAULT_WALL_MATERIAL = 3000, MATERIAL_SILVER = 750, MATERIAL_URANIUM = 250)
build_path = /obj/item/deployable_kit/remote_mech
/datum/design/item/deployable_kit/mech_chair/brig
name = "Remote Penal Mech Centre"
desc = "A deployable kit of a remote mech chair, capable of listening in to penal remote mech networks."
build_path = /obj/item/deployable_kit/remote_mech/brig

View File

@@ -100,6 +100,8 @@
/obj/structure/lift/panel/interact(var/mob/user) /obj/structure/lift/panel/interact(var/mob/user)
if(!..()) if(!..())
return return
if(istype(user, /mob/living/heavy_vehicle)) // terrible, i know, but it shat out runtimes otherwise
user = usr
var/dat = list() var/dat = list()
dat += "<html><body><hr><b>Lift panel</b><hr>" dat += "<html><body><hr><b>Lift panel</b><hr>"

View File

@@ -0,0 +1,13 @@
author: Geeves
delete-after: True
changes:
- rscadd: "The AI can now remotely control mechs in its network. It has one mapped in near its core."
- rscadd: "Messages received by your old body will now reach your VR body (does not affect Skrell Srom)."
- bugfix: "Exosuit pilots can now interact with elevator panels without having to get out."
- rscadd: "Robotics and RnD can now create remote controlled mechs. The control centre is in the protolathe, while the exosuit upgrade is in the circuit imprinter."
- tweak: "Mechs can no longer be dismantled if it has a pilot in it."
- tweak: "Dismantling a mech now takes a while."
- bugfix: "Mechs can no longer be buckled to chairs or beds."
- bugfix: "AIs now properly ghost after dying."

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

File diff suppressed because it is too large Load Diff