mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-25 08:34:23 +00:00
## About The Pull Request This does nothing currently, but will allow me to test for layering issues on LIVE, rather then in just wallening. Oh also I'm packaging in a fix to one of my macros that I wrote wrong, as a joke [removes SEE_BLACKNESS usage, because we actually cannot use it effectively](c9a19dd7cc) [c9a19dd](c9a19dd7cc) Sidemap removes the ability to control it on a plane, so it basically just means there's an uncontrollable black slate even if you have other toggles set. This just like, removes that, since it's silly [fixes weird layering on solars and ai portraits. Pixel y was casuing things to render below who shouldn't](3885b9d9ed) [3885b9d](3885b9d9ed) [Fixes flicker issues](2defc0ad20) [2defc0a](2defc0ad20) Offsetting the vis_contents'd objects down physically, and then up visually resolves the confliciting that was going on between the text and its display. This resolves the existing reported flickering issues [fixes plated food not appearing in world](28a34c64f8) [28a34c6](28a34c64f8) pixel_y'd vis_contents strikes again. It's a tad hacky but we'll just use pixel_z for this [Adds wall and upper wall plane masters](89fe2b4eb4) [89fe2b4](89fe2b4eb4) We use these + the floor and space planes to build a mask of all the visible turfs. Then we take that, stick it in a plane master, and mask the emissive plane with it. This solves the lighting fulldark screen object getting cut by emissives Shifts some planes around to match this new layering. Also ensures we only shift fullscreen objects if they don't object to it. [compresses plane master controllers](bd64cc196a) [bd64cc1](bd64cc196a) we don't use them for much rn, but we might in future so I'm keeping it as a convienince thing 🆑 refactor: The logic of how we well, render things has changed. Make an issue report if anything looks funky, particularly layers. PLEASE USE YOUR EYES /🆑 Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
403 lines
15 KiB
Plaintext
403 lines
15 KiB
Plaintext
/obj/machinery/computer/camera_advanced/shuttle_docker
|
|
name = "navigation computer"
|
|
desc = "Used to designate a precise transit location for a spacecraft."
|
|
jump_action = null
|
|
should_supress_view_changes = FALSE
|
|
|
|
// Docking cameras should only interact with their current z-level.
|
|
move_up_action = null
|
|
move_down_action = null
|
|
|
|
var/shuttleId = ""
|
|
var/shuttlePortId = ""
|
|
var/shuttlePortName = "custom location"
|
|
/// Hashset of ports to jump to and ignore for collision purposes
|
|
var/list/jump_to_ports = list()
|
|
/// The custom docking port placed by this console
|
|
var/obj/docking_port/stationary/my_port
|
|
/// The mobile docking port of the connected shuttle
|
|
var/obj/docking_port/mobile/shuttle_port
|
|
// Traits forbided for custom docking
|
|
var/list/locked_traits = list(ZTRAIT_RESERVED, ZTRAIT_CENTCOM, ZTRAIT_AWAY)
|
|
var/view_range = 0
|
|
var/x_offset = 0
|
|
var/y_offset = 0
|
|
var/list/whitelist_turfs = list(/turf/open/space, /turf/open/floor/plating, /turf/open/lava, /turf/open/openspace)
|
|
var/see_hidden = FALSE
|
|
var/designate_time = 0
|
|
var/turf/designating_target_loc
|
|
var/jammed = FALSE
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/Initialize(mapload)
|
|
. = ..()
|
|
GLOB.navigation_computers += src
|
|
actions += new /datum/action/innate/shuttledocker_rotate(src)
|
|
actions += new /datum/action/innate/shuttledocker_place(src)
|
|
|
|
set_init_ports()
|
|
|
|
if(connect_to_shuttle(mapload, SSshuttle.get_containing_shuttle(src)))
|
|
for(var/obj/docking_port/stationary/port as anything in SSshuttle.stationary_docking_ports)
|
|
if(port.shuttle_id == shuttleId)
|
|
add_jumpable_port(port.shuttle_id)
|
|
|
|
for(var/obj/docking_port/stationary/port as anything in SSshuttle.stationary_docking_ports)
|
|
if(!port)
|
|
continue
|
|
if(jump_to_ports[port.shuttle_id])
|
|
z_lock |= port.z
|
|
whitelist_turfs = typecacheof(whitelist_turfs)
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/Destroy()
|
|
. = ..()
|
|
GLOB.navigation_computers -= src
|
|
|
|
if(my_port?.get_docked())
|
|
my_port.delete_after = TRUE
|
|
my_port.shuttle_id = null
|
|
my_port.name = "Old [my_port.name]"
|
|
my_port = null
|
|
else
|
|
QDEL_NULL(my_port)
|
|
|
|
/// "Initializes" any default port ids we have, done so add_jumpable_port can be a proper setter
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/set_init_ports()
|
|
var/list/init_ports = jump_to_ports.Copy()
|
|
jump_to_ports = list() //Reset it so we don't get dupes
|
|
for(var/port_id in init_ports)
|
|
add_jumpable_port(port_id)
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/add_jumpable_port(port_id)
|
|
if(!length(jump_to_ports))
|
|
actions += new /datum/action/innate/camera_jump/shuttle_docker(src)
|
|
jump_to_ports[port_id] = TRUE
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/remove_jumpable_port(port_id)
|
|
jump_to_ports -= port_id
|
|
if(!length(jump_to_ports))
|
|
var/datum/action/to_remove = locate(/datum/action/innate/camera_jump/shuttle_docker) in actions
|
|
actions -= to_remove
|
|
qdel(to_remove)
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/attack_hand(mob/user, list/modifiers)
|
|
if(jammed)
|
|
to_chat(user, span_warning("The Syndicate is jamming the console!"))
|
|
return
|
|
if(!shuttle_port && !SSshuttle.getShuttle(shuttleId))
|
|
to_chat(user,span_warning("Warning: Shuttle connection severed!"))
|
|
return
|
|
return ..()
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/CreateEye()
|
|
shuttle_port = SSshuttle.getShuttle(shuttleId)
|
|
if(QDELETED(shuttle_port))
|
|
shuttle_port = null
|
|
return
|
|
|
|
eyeobj = new /mob/camera/ai_eye/remote/shuttle_docker(null, src)
|
|
var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
|
|
the_eye.setDir(shuttle_port.dir)
|
|
var/turf/origin = locate(shuttle_port.x + x_offset, shuttle_port.y + y_offset, shuttle_port.z)
|
|
for(var/V in shuttle_port.shuttle_areas)
|
|
var/area/A = V
|
|
for(var/turf/T in A)
|
|
if(T.z != origin.z)
|
|
continue
|
|
var/image/I = image('icons/effects/alphacolors.dmi', origin, "red")
|
|
var/x_off = T.x - origin.x
|
|
var/y_off = T.y - origin.y
|
|
I.loc = locate(origin.x + x_off, origin.y + y_off, origin.z) //we have to set this after creating the image because it might be null, and images created in nullspace are immutable.
|
|
I.layer = ABOVE_NORMAL_TURF_LAYER
|
|
SET_PLANE(I, ABOVE_GAME_PLANE, T)
|
|
I.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
|
the_eye.placement_images[I] = list(x_off, y_off)
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/give_eye_control(mob/user)
|
|
..()
|
|
if(!QDELETED(user) && user.client)
|
|
var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
|
|
var/list/to_add = list()
|
|
to_add += the_eye.placement_images
|
|
to_add += the_eye.placed_images
|
|
if(!see_hidden)
|
|
to_add += SSshuttle.hidden_shuttle_turf_images
|
|
|
|
user.client.images += to_add
|
|
user.client.view_size.setTo(view_range)
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/remove_eye_control(mob/living/user)
|
|
..()
|
|
if(!QDELETED(user) && user.client)
|
|
var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
|
|
var/list/to_remove = list()
|
|
to_remove += the_eye.placement_images
|
|
to_remove += the_eye.placed_images
|
|
if(!see_hidden)
|
|
to_remove += SSshuttle.hidden_shuttle_turf_images
|
|
|
|
user.client.images -= to_remove
|
|
user.client.view_size.resetToDefault()
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/placeLandingSpot()
|
|
if(designating_target_loc || !current_user)
|
|
return
|
|
|
|
var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
|
|
var/landing_clear = checkLandingSpot()
|
|
if(designate_time && (landing_clear != SHUTTLE_DOCKER_BLOCKED))
|
|
to_chat(current_user, span_warning("Targeting transit location, please wait [DisplayTimeText(designate_time)]..."))
|
|
designating_target_loc = the_eye.loc
|
|
var/wait_completed = do_after(current_user, designate_time, designating_target_loc, timed_action_flags = IGNORE_HELD_ITEM, extra_checks = CALLBACK(src, TYPE_PROC_REF(/obj/machinery/computer/camera_advanced/shuttle_docker, canDesignateTarget)))
|
|
designating_target_loc = null
|
|
if(!current_user)
|
|
return
|
|
if(!wait_completed)
|
|
to_chat(current_user, span_warning("Operation aborted."))
|
|
return
|
|
landing_clear = checkLandingSpot()
|
|
|
|
if(landing_clear != SHUTTLE_DOCKER_LANDING_CLEAR)
|
|
switch(landing_clear)
|
|
if(SHUTTLE_DOCKER_BLOCKED)
|
|
to_chat(current_user, span_warning("Invalid transit location."))
|
|
if(SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT)
|
|
to_chat(current_user, span_warning("Unknown object detected in landing zone. Please designate another location."))
|
|
return
|
|
|
|
///Make one use port that deleted after fly off, to don't lose info that need on to properly fly off.
|
|
if(my_port?.get_docked())
|
|
my_port.unregister()
|
|
my_port.delete_after = TRUE
|
|
my_port.shuttle_id = null
|
|
my_port.name = "Old [my_port.name]"
|
|
my_port = null
|
|
|
|
if(!my_port)
|
|
my_port = new()
|
|
my_port.unregister()
|
|
my_port.name = shuttlePortName
|
|
my_port.shuttle_id = shuttlePortId
|
|
my_port.height = shuttle_port.height
|
|
my_port.width = shuttle_port.width
|
|
my_port.dheight = shuttle_port.dheight
|
|
my_port.dwidth = shuttle_port.dwidth
|
|
my_port.hidden = shuttle_port.hidden
|
|
my_port.register(TRUE)
|
|
my_port.setDir(the_eye.dir)
|
|
my_port.forceMove(locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z))
|
|
|
|
if(current_user.client)
|
|
current_user.client.images -= the_eye.placed_images
|
|
|
|
QDEL_LIST(the_eye.placed_images)
|
|
|
|
for(var/V in the_eye.placement_images)
|
|
var/image/I = V
|
|
var/image/newI = image('icons/effects/alphacolors.dmi', the_eye.loc, "blue")
|
|
newI.loc = I.loc //It is highly unlikely that any landing spot including a null tile will get this far, but better safe than sorry.
|
|
newI.layer = NAVIGATION_EYE_LAYER
|
|
SET_PLANE_EXPLICIT(newI, ABOVE_GAME_PLANE, V)
|
|
newI.mouse_opacity = 0
|
|
the_eye.placed_images += newI
|
|
|
|
if(current_user.client)
|
|
current_user.client.images += the_eye.placed_images
|
|
to_chat(current_user, span_notice("Transit location designated."))
|
|
return TRUE
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/canDesignateTarget()
|
|
if(!designating_target_loc || !current_user || (eyeobj.loc != designating_target_loc) || (machine_stat & (NOPOWER|BROKEN)) )
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/rotateLandingSpot()
|
|
var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
|
|
var/list/image_cache = the_eye.placement_images
|
|
the_eye.setDir(turn(the_eye.dir, -90))
|
|
for(var/i in 1 to image_cache.len)
|
|
var/image/pic = image_cache[i]
|
|
var/list/coords = image_cache[pic]
|
|
var/Tmp = coords[1]
|
|
coords[1] = coords[2]
|
|
coords[2] = -Tmp
|
|
pic.loc = locate(the_eye.x + coords[1], the_eye.y + coords[2], the_eye.z)
|
|
var/Tmp = x_offset
|
|
x_offset = y_offset
|
|
y_offset = -Tmp
|
|
checkLandingSpot()
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/checkLandingSpot()
|
|
var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
|
|
var/turf/eyeturf = get_turf(the_eye)
|
|
if(!eyeturf)
|
|
return SHUTTLE_DOCKER_BLOCKED
|
|
if(!eyeturf.z || SSmapping.level_has_any_trait(eyeturf.z, locked_traits))
|
|
return SHUTTLE_DOCKER_BLOCKED
|
|
|
|
. = SHUTTLE_DOCKER_LANDING_CLEAR
|
|
var/list/bounds = shuttle_port.return_coords(the_eye.x - x_offset, the_eye.y - y_offset, the_eye.dir)
|
|
var/list/overlappers = SSshuttle.get_dock_overlap(bounds[1], bounds[2], bounds[3], bounds[4], the_eye.z)
|
|
var/list/image_cache = the_eye.placement_images
|
|
for(var/i in 1 to image_cache.len)
|
|
var/image/I = image_cache[i]
|
|
var/list/coords = image_cache[I]
|
|
var/turf/T = locate(eyeturf.x + coords[1], eyeturf.y + coords[2], eyeturf.z)
|
|
I.loc = T
|
|
switch(checkLandingTurf(T, overlappers))
|
|
if(SHUTTLE_DOCKER_LANDING_CLEAR)
|
|
I.icon_state = "green"
|
|
if(SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT)
|
|
I.icon_state = "green"
|
|
if(. == SHUTTLE_DOCKER_LANDING_CLEAR)
|
|
. = SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT
|
|
else
|
|
I.icon_state = "red"
|
|
. = SHUTTLE_DOCKER_BLOCKED
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/checkLandingTurf(turf/T, list/overlappers)
|
|
// Too close to the map edge is never allowed
|
|
if(!T || T.x <= 10 || T.y <= 10 || T.x >= world.maxx - 10 || T.y >= world.maxy - 10)
|
|
return SHUTTLE_DOCKER_BLOCKED
|
|
// If it's one of our shuttle areas assume it's ok to be there
|
|
if(shuttle_port.shuttle_areas[T.loc])
|
|
return SHUTTLE_DOCKER_LANDING_CLEAR
|
|
. = SHUTTLE_DOCKER_LANDING_CLEAR
|
|
// See if the turf is hidden from us
|
|
var/list/hidden_turf_info
|
|
if(!see_hidden)
|
|
hidden_turf_info = SSshuttle.hidden_shuttle_turfs[T]
|
|
if(hidden_turf_info)
|
|
. = SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT
|
|
|
|
if(length(whitelist_turfs))
|
|
var/turf_type = hidden_turf_info ? hidden_turf_info[2] : T.type
|
|
if(!is_type_in_typecache(turf_type, whitelist_turfs))
|
|
return SHUTTLE_DOCKER_BLOCKED
|
|
|
|
// Checking for overlapping dock boundaries
|
|
for(var/i in 1 to overlappers.len)
|
|
var/obj/docking_port/port = overlappers[i]
|
|
if(port == my_port)
|
|
continue
|
|
var/port_hidden = !see_hidden && port.hidden
|
|
var/list/overlap = overlappers[port]
|
|
var/list/xs = overlap[1]
|
|
var/list/ys = overlap[2]
|
|
if(xs["[T.x]"] && ys["[T.y]"])
|
|
if(port_hidden)
|
|
. = SHUTTLE_DOCKER_BLOCKED_BY_HIDDEN_PORT
|
|
else
|
|
return SHUTTLE_DOCKER_BLOCKED
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/update_hidden_docking_ports(list/remove_images, list/add_images)
|
|
if(!see_hidden && current_user?.client)
|
|
current_user.client.images -= remove_images
|
|
current_user.client.images += add_images
|
|
|
|
/obj/machinery/computer/camera_advanced/shuttle_docker/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
|
|
if(!mapload)
|
|
return FALSE
|
|
if(port)
|
|
shuttleId = port.shuttle_id
|
|
shuttlePortId = "[port.shuttle_id]_custom"
|
|
if(dock)
|
|
add_jumpable_port(dock.shuttle_id)
|
|
return TRUE
|
|
|
|
/mob/camera/ai_eye/remote/shuttle_docker
|
|
visible_icon = FALSE
|
|
use_static = FALSE
|
|
var/list/placement_images = list()
|
|
var/list/placed_images = list()
|
|
|
|
/mob/camera/ai_eye/remote/shuttle_docker/Initialize(mapload, obj/machinery/computer/camera_advanced/origin)
|
|
src.origin = origin
|
|
return ..()
|
|
|
|
/mob/camera/ai_eye/remote/shuttle_docker/setLoc(turf/destination, force_update = FALSE)
|
|
. = ..()
|
|
var/obj/machinery/computer/camera_advanced/shuttle_docker/console = origin
|
|
console.checkLandingSpot()
|
|
|
|
/mob/camera/ai_eye/remote/shuttle_docker/update_remote_sight(mob/living/user)
|
|
user.set_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"
|
|
button_icon = 'icons/mob/actions/actions_mecha.dmi'
|
|
button_icon_state = "mech_cycle_equip_off"
|
|
|
|
/datum/action/innate/shuttledocker_rotate/Activate()
|
|
if(QDELETED(owner) || !isliving(owner))
|
|
return
|
|
var/mob/camera/ai_eye/remote/remote_eye = owner.remote_control
|
|
var/obj/machinery/computer/camera_advanced/shuttle_docker/origin = remote_eye.origin
|
|
origin.rotateLandingSpot()
|
|
|
|
/datum/action/innate/shuttledocker_place
|
|
name = "Place"
|
|
button_icon = 'icons/mob/actions/actions_mecha.dmi'
|
|
button_icon_state = "mech_zoom_off"
|
|
|
|
/datum/action/innate/shuttledocker_place/Activate()
|
|
if(QDELETED(owner) || !isliving(owner))
|
|
return
|
|
var/mob/camera/ai_eye/remote/remote_eye = owner.remote_control
|
|
var/obj/machinery/computer/camera_advanced/shuttle_docker/origin = remote_eye.origin
|
|
origin.placeLandingSpot(owner)
|
|
|
|
/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(owner) || !isliving(owner))
|
|
return
|
|
var/mob/camera/ai_eye/remote/remote_eye = owner.remote_control
|
|
var/obj/machinery/computer/camera_advanced/shuttle_docker/console = remote_eye.origin
|
|
|
|
playsound(console, 'sound/machines/terminal_prompt_deny.ogg', 25, FALSE)
|
|
|
|
var/list/L = list()
|
|
for(var/V in SSshuttle.stationary_docking_ports)
|
|
if(!V)
|
|
stack_trace("SSshuttle.stationary_docking_ports have null entry!")
|
|
continue
|
|
var/obj/docking_port/stationary/S = V
|
|
if(console.z_lock.len && !(S.z in console.z_lock))
|
|
continue
|
|
if(console.jump_to_ports[S.shuttle_id])
|
|
L["([L.len])[S.name]"] = S
|
|
|
|
for(var/V in SSshuttle.beacon_list)
|
|
if(!V)
|
|
stack_trace("SSshuttle.beacon_list have null entry!")
|
|
continue
|
|
var/obj/machinery/spaceship_navigation_beacon/nav_beacon = V
|
|
if(!nav_beacon.z || SSmapping.level_has_any_trait(nav_beacon.z, console.locked_traits))
|
|
break
|
|
if(!nav_beacon.locked)
|
|
L["([L.len]) [nav_beacon.name] located: [nav_beacon.x] [nav_beacon.y] [nav_beacon.z]"] = nav_beacon
|
|
else
|
|
L["([L.len]) [nav_beacon.name] locked"] = null
|
|
|
|
playsound(console, 'sound/machines/terminal_prompt.ogg', 25, FALSE)
|
|
var/selected = tgui_input_list(usr, "Choose location to jump to", "Locations", sort_list(L))
|
|
if(isnull(selected))
|
|
playsound(console, 'sound/machines/terminal_prompt_deny.ogg', 25, FALSE)
|
|
return
|
|
if(QDELETED(src) || QDELETED(owner) || !isliving(owner))
|
|
return
|
|
playsound(src, SFX_TERMINAL_TYPE, 25, FALSE)
|
|
var/turf/T = get_turf(L[selected])
|
|
if(isnull(T))
|
|
return
|
|
playsound(console, 'sound/machines/terminal_prompt_confirm.ogg', 25, FALSE)
|
|
remote_eye.setLoc(T)
|
|
to_chat(owner, span_notice("Jumped to [selected]."))
|
|
owner.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash/static)
|
|
owner.clear_fullscreen("flash", 3)
|