diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index aa906283888..ce100c807a5 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -60614,8 +60614,7 @@ }, /area/shuttle/syndicate) "cIn" = ( -/obj/structure/table/reinforced, -/obj/item/folder/red, +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -60650,10 +60649,11 @@ pixel_x = -32 }, /obj/item/clipboard, -/obj/item/toy/figure/syndie, /obj/machinery/light{ dir = 8 }, +/obj/item/folder/red, +/obj/item/toy/figure/syndie, /turf/open/floor/plasteel/vault{ dir = 8 }, diff --git a/_maps/map_files/Cerestation/cerestation.dmm b/_maps/map_files/Cerestation/cerestation.dmm index 86ac838e9fc..811996dbdae 100644 --- a/_maps/map_files/Cerestation/cerestation.dmm +++ b/_maps/map_files/Cerestation/cerestation.dmm @@ -1,4 +1,4 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "aaa" = ( /turf/open/space, /area/space) @@ -72742,10 +72742,11 @@ pixel_x = -32 }, /obj/item/clipboard, -/obj/item/toy/figure/syndie, /obj/machinery/light{ dir = 8 }, +/obj/item/folder/red, +/obj/item/toy/figure/syndie, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -72784,10 +72785,10 @@ }, /area/shuttle/syndicate) "fXq" = ( +/turf/open/space, /obj/machinery/porta_turret/syndicate{ dir = 9 }, -/turf/open/space, /turf/closed/wall/mineral/plastitanium{ dir = 8; icon_state = "diagonalWall3" @@ -73544,10 +73545,10 @@ /turf/open/floor/plasteel/floorgrime, /area/maintenance/asteroid/disposal/south) "qah" = ( +/turf/open/space, /obj/machinery/porta_turret/syndicate{ dir = 10 }, -/turf/open/space, /turf/closed/wall/mineral/plastitanium{ icon_state = "diagonalWall3" }, @@ -75054,8 +75055,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit) "HmY" = ( -/obj/structure/table/reinforced, -/obj/item/folder/red, +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -76501,10 +76501,10 @@ /turf/open/floor/plating, /area/maintenance/asteroid/disposal/south/west) "ZfX" = ( +/turf/open/space, /obj/machinery/porta_turret/syndicate{ dir = 5 }, -/turf/open/space, /turf/closed/wall/mineral/plastitanium{ dir = 1; icon_state = "diagonalWall3" @@ -76532,10 +76532,10 @@ }, /area/shuttle/syndicate) "ZYy" = ( +/turf/open/space, /obj/machinery/porta_turret/syndicate{ dir = 6 }, -/turf/open/space, /turf/closed/wall/mineral/plastitanium{ dir = 4; icon_state = "diagonalWall3" diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 6c678d3cd49..da4fe635d8e 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -1714,8 +1714,7 @@ }, /area/shuttle/syndicate) "adC" = ( -/obj/structure/table/reinforced, -/obj/item/folder/red, +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -1840,10 +1839,11 @@ pixel_x = -32 }, /obj/item/clipboard, -/obj/item/toy/figure/syndie, /obj/machinery/light{ dir = 8 }, +/obj/item/folder/red, +/obj/item/toy/figure/syndie, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -138762,13 +138762,13 @@ bZC duO cJx cHS -cMI -cMI -cMI +cHX +cHX +cHX cRJ -cMI -cMI -cMI +cHX +cHX +cHX cHS cJA cFm @@ -139276,13 +139276,13 @@ cBp erO cJz cHS -cMI -cMI -cMI -cMI -cMI -cMI -cMI +cHX +cHX +cHX +cHX +cHX +cHX +cHX cHS cZL dbc @@ -139535,8 +139535,8 @@ cJA cHS cHS cOs -cMI -cMI +cHX +cHX cTv cOs cHS @@ -155472,7 +155472,7 @@ cPm cLL cSA cUj -cVW +cUu cXJ cZi dap diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 0eb1286d501..4511bfe5820 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -78644,8 +78644,7 @@ /turf/open/floor/plating, /area/science/xenobiology) "cTE" = ( -/obj/structure/table/reinforced, -/obj/item/folder/red, +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -78668,10 +78667,11 @@ pixel_x = -32 }, /obj/item/clipboard, -/obj/item/toy/figure/syndie, /obj/machinery/light{ dir = 8 }, +/obj/item/folder/red, +/obj/item/toy/figure/syndie, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -136448,8 +136448,8 @@ cgD chW cjl ckK -bCC -bCC +dbu +dbu ckM aaf bKK @@ -136704,9 +136704,9 @@ ccY ccY ccY cjm -bCC +dbu cme -bCC +dbu cjo aaa bKK @@ -136962,8 +136962,8 @@ cgE chX cjn ckL -bCC -bCC +dbu +dbu bxc aaf aai diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 2fc2c473e87..028c958e3e4 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -37022,8 +37022,7 @@ }, /area/shuttle/syndicate) "bmZ" = ( -/obj/structure/table/reinforced, -/obj/item/folder/red, +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -37062,10 +37061,11 @@ pixel_x = -32 }, /obj/item/clipboard, -/obj/item/toy/figure/syndie, /obj/machinery/light{ dir = 8 }, +/obj/item/folder/red, +/obj/item/toy/figure/syndie, /turf/open/floor/plasteel/vault{ dir = 8 }, diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 272e5829d1f..7f55c286c77 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -46,8 +46,7 @@ }, /area/shuttle/syndicate) "aah" = ( -/obj/structure/table/reinforced, -/obj/item/folder/red, +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -82,10 +81,11 @@ pixel_x = -32 }, /obj/item/clipboard, -/obj/item/toy/figure/syndie, /obj/machinery/light{ dir = 8 }, +/obj/item/folder/red, +/obj/item/toy/figure/syndie, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -80202,9 +80202,9 @@ bva bva bva aht -crn +bIZ crA -crn +bIZ aaa bva bva @@ -103021,7 +103021,7 @@ aNR aNR aTu aUB -cpd +aEl aaa aaa aEl diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm new file mode 100644 index 00000000000..32324ea233d --- /dev/null +++ b/code/modules/shuttle/navigation_computer.dm @@ -0,0 +1,244 @@ +/obj/machinery/computer/camera_advanced/shuttle_docker + name = "navigation computer" + desc = "Used to designate a precise transit location for a spacecraft." + z_lock = ZLEVEL_STATION + jump_action = null + var/datum/action/innate/shuttledocker_rotate/rotate_action = new + var/datum/action/innate/shuttledocker_place/place_action = new + var/shuttleId = "" + var/shuttlePortId = "" + var/shuttlePortName = "" + var/list/jumpto_ports = list() //hashset of ports to jump to and ignore for collision purposes + var/list/blacklisted_turfs + var/obj/docking_port/stationary/my_port + var/view_range = 7 + var/x_offset = 0 + var/y_offset = 0 + var/space_turfs_only = TRUE + +/obj/machinery/computer/camera_advanced/shuttle_docker/GrantActions(mob/living/user) + if(jumpto_ports.len) + jump_action = new /datum/action/innate/camera_jump/shuttle_docker + ..() + + if(rotate_action) + rotate_action.target = user + rotate_action.Grant(user) + actions += rotate_action + + if(place_action) + place_action.target = user + place_action.Grant(user) + actions += place_action + +/obj/machinery/computer/camera_advanced/shuttle_docker/CreateEye() + var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) + if(QDELETED(M)) + return + eyeobj = new /mob/camera/aiEye/remote/shuttle_docker() + var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj + the_eye.origin = src + the_eye.dir = M.dir + var/area/A = get_area(M) + if(QDELETED(A)) + return + var/turf/origin = locate(M.x + x_offset, M.y + y_offset, M.z) + for(var/turf/T in A) + if(T.z != origin.z) + continue + var/image/I = image('icons/effects/alphacolors.dmi', origin, "red") + I.layer = ABOVE_NORMAL_TURF_LAYER + I.plane = 0 + I.mouse_opacity = 0 + var/x_off = T.x - origin.x + var/y_off = T.y - origin.y + I.pixel_x = x_off * 32 + I.pixel_y = y_off * 32 + the_eye.placement_images[I] = list(x_off, y_off) + generateBlacklistedTurfs() + +/obj/machinery/computer/camera_advanced/shuttle_docker/give_eye_control(mob/user) + ..() + if(!QDELETED(user) && user.client) + var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj + user.client.images += the_eye.placement_images + user.client.images += the_eye.placed_images + user.client.view = view_range + +/obj/machinery/computer/camera_advanced/shuttle_docker/remove_eye_control(mob/living/user) + ..() + if(!QDELETED(user) && user.client) + var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj + user.client.images -= the_eye.placement_images + user.client.images -= the_eye.placed_images + user.client.view = world.view + +/obj/machinery/computer/camera_advanced/shuttle_docker/proc/placeLandingSpot() + if(!checkLandingSpot()) + return FALSE + var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj + if(!my_port) + my_port = new /obj/docking_port/stationary + my_port.name = shuttlePortName + my_port.id = shuttlePortId + var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) + my_port.height = M.height + my_port.width = M.width + my_port.dheight = M.dheight + my_port.dwidth = M.dwidth + my_port.dir = the_eye.dir + my_port.loc = locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z) + if(current_user && current_user.client) + current_user.client.images -= the_eye.placed_images + + for(var/V in the_eye.placed_images) + qdel(V) + the_eye.placed_images = list() + + for(var/V in the_eye.placement_images) + var/turf/T = locate(eyeobj.x + the_eye.placement_images[V][1], eyeobj.y + the_eye.placement_images[V][2], eyeobj.z) + var/image/I = image('icons/effects/alphacolors.dmi', T, "blue") + I.layer = ABOVE_OPEN_TURF_LAYER + I.plane = 0 + I.mouse_opacity = 0 + the_eye.placed_images += I + + if(current_user && current_user.client) + current_user.client.images += the_eye.placed_images + return TRUE + +/obj/machinery/computer/camera_advanced/shuttle_docker/proc/rotateLandingSpot() + var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj + the_eye.dir = turn(the_eye.dir, -90) + for(var/V in the_eye.placement_images) + var/image/I = V + var/list/coords = the_eye.placement_images[V] + var/Tmp = coords[1] + coords[1] = coords[2] + coords[2] = -Tmp + + I.pixel_x = coords[1] * 32 + I.pixel_y = coords[2] * 32 + var/Tmp = x_offset + x_offset = y_offset + y_offset = -Tmp + checkLandingSpot() + +/obj/machinery/computer/camera_advanced/shuttle_docker/proc/checkLandingTurf(turf/T) + return T && (!blacklisted_turfs || !blacklisted_turfs[T]) && (!space_turfs_only || isspaceturf(T)) + +/obj/machinery/computer/camera_advanced/shuttle_docker/proc/generateBlacklistedTurfs() + blacklisted_turfs = list() + for(var/V in SSshuttle.stationary) + if(!V) + continue + var/obj/docking_port/stationary/S = V + if(z_lock && (S.z != z_lock)) + continue + if((S.id == shuttlePortId) || jumpto_ports[S.id]) + continue + for(var/T in S.return_turfs()) + blacklisted_turfs[T] = TRUE + +/obj/machinery/computer/camera_advanced/shuttle_docker/proc/checkLandingSpot() + var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj + var/turf/eyeturf = get_turf(the_eye) + if(!eyeturf) + return + var/landing_spot_clear = TRUE + for(var/V in the_eye.placement_images) + var/image/I = V + I.loc = eyeturf + var/list/coords = the_eye.placement_images[V] + var/turf/T = locate(eyeturf.x + coords[1], eyeturf.y + coords[2], eyeturf.z) + if(checkLandingTurf(T)) + I.icon_state = "green" + else + I.icon_state = "red" + landing_spot_clear = FALSE + return landing_spot_clear + +/mob/camera/aiEye/remote/shuttle_docker + visible_icon = FALSE + use_static = FALSE + var/list/placement_images = list() + var/list/placed_images = list() + +/mob/camera/aiEye/remote/shuttle_docker/setLoc(T) + ..() + var/obj/machinery/computer/camera_advanced/shuttle_docker/console = origin + console.checkLandingSpot() + +/mob/camera/aiEye/remote/shuttle_docker/update_remote_sight(mob/living/user) + user.sight = BLIND|SEE_TURFS + user.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE + user.sync_lighting_plane_alpha() + return TRUE + +/datum/action/innate/shuttledocker_rotate + name = "Rotate" + icon_icon = 'icons/mob/actions/actions_mecha.dmi' + button_icon_state = "mech_cycle_equip_off" + +/datum/action/innate/shuttledocker_rotate/Activate() + if(QDELETED(target) || !isliving(target)) + return + var/mob/living/C = target + var/mob/camera/aiEye/remote/remote_eye = C.remote_control + var/obj/machinery/computer/camera_advanced/shuttle_docker/origin = remote_eye.origin + origin.rotateLandingSpot() + +/datum/action/innate/shuttledocker_place + name = "Place" + icon_icon = 'icons/mob/actions/actions_mecha.dmi' + button_icon_state = "mech_zoom_off" + +/datum/action/innate/shuttledocker_place/Activate() + if(QDELETED(target) || !isliving(target)) + return + var/mob/living/C = target + var/mob/camera/aiEye/remote/remote_eye = C.remote_control + var/obj/machinery/computer/camera_advanced/shuttle_docker/origin = remote_eye.origin + if(origin.placeLandingSpot()) + to_chat(target, "Transit location designated") + else + to_chat(target, "Invalid transit location") + +/datum/action/innate/camera_jump/shuttle_docker + name = "Jump to Location" + button_icon_state = "camera_jump" + +/datum/action/innate/camera_jump/shuttle_docker/Activate() + if(QDELETED(target) || !isliving(target)) + return + var/mob/living/C = target + var/mob/camera/aiEye/remote/remote_eye = C.remote_control + var/obj/machinery/computer/camera_advanced/shuttle_docker/console = remote_eye.origin + + playsound(console, 'sound/machines/terminal_prompt_deny.ogg', 25, 0) + + var/list/L = list() + for(var/V in SSshuttle.stationary) + if(!V) + continue + var/obj/docking_port/stationary/S = V + if(console.z_lock && (S.z != console.z_lock)) + continue + if(console.jumpto_ports[S.id]) + L[S.name] = S + + playsound(console, 'sound/machines/terminal_prompt.ogg', 25, 0) + var/selected = input("Choose location to jump to", "Locations", null) as null|anything in L + if(QDELETED(src) || QDELETED(target) || !isliving(target)) + return + playsound(src, "terminal_type", 25, 0) + if(selected) + var/turf/T = get_turf(L[selected]) + if(T) + playsound(console, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0) + remote_eye.setLoc(T) + to_chat(target, "Jumped to [selected]") + C.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static) + C.clear_fullscreen("flash", 3) + else + playsound(console, 'sound/machines/terminal_prompt_deny.ogg', 25, 0) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 61981d3867b..d0d5952a0c8 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -71,6 +71,12 @@ _y + (-dwidth+width-1)*sin + (-dheight+height-1)*cos ) +//returns turfs within our projected rectangle in no particular order +/obj/docking_port/proc/return_turfs() + var/list/L = return_coords() + var/turf/T0 = locate(L[1],L[2],z) + var/turf/T1 = locate(L[3],L[4],z) + return block(T0,T1) //returns turfs within our projected rectangle in a specific order. //this ensures that turfs are copied over in the same order, regardless of any rotation diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm index 0a610cc6361..f9d90dd3426 100644 --- a/code/modules/shuttle/syndicate.dm +++ b/code/modules/shuttle/syndicate.dm @@ -8,7 +8,7 @@ light_color = LIGHT_COLOR_RED req_access = list(ACCESS_SYNDICATE) shuttleId = "syndicate" - possible_destinations = "syndicate_away;syndicate_z5;syndicate_ne;syndicate_nw;syndicate_n;syndicate_se;syndicate_sw;syndicate_s" + possible_destinations = "syndicate_away;syndicate_z5;syndicate_ne;syndicate_nw;syndicate_n;syndicate_se;syndicate_sw;syndicate_s;syndicate_custom" resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF /obj/machinery/computer/shuttle/syndicate/recall @@ -42,5 +42,18 @@ return 0 ..() +/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate + name = "syndicate shuttle navigation computer" + desc = "Used to designate a precise transit location for the syndicate shuttle." + icon_screen = "syndishuttle" + icon_keyboard = "syndie_key" + z_lock = ZLEVEL_STATION + shuttleId = "syndicate" + shuttlePortId = "syndicate_custom" + shuttlePortName = "custom location" + jumpto_ports = list("syndicate_ne" = 1, "syndicate_nw" = 1, "syndicate_n" = 1, "syndicate_se" = 1, "syndicate_sw" = 1, "syndicate_s" = 1) + view_range = 13 + x_offset = -4 + y_offset = -2 #undef SYNDICATE_CHALLENGE_TIMER \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 0c345008035..0f4b25199b0 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2048,6 +2048,7 @@ #include "code\modules\shuttle\emergency.dm" #include "code\modules\shuttle\ferry.dm" #include "code\modules\shuttle\manipulator.dm" +#include "code\modules\shuttle\navigation_computer.dm" #include "code\modules\shuttle\on_move.dm" #include "code\modules\shuttle\ripple.dm" #include "code\modules\shuttle\shuttle.dm"