[Ready] Shuttle dock() rewrite (#2040)
This commit is contained in:
committed by
kevinz000
parent
bbc28aa856
commit
e522f715a2
@@ -4,7 +4,7 @@
|
||||
dwidth = 3
|
||||
width = 7
|
||||
height = 7
|
||||
knockdown = FALSE
|
||||
movement_force = list("KNOCKDOWN" = 0, "THROW" = 0)
|
||||
|
||||
/obj/docking_port/mobile/elevator/request(obj/docking_port/stationary/S) //No transit, no ignition, just a simple up/down platform
|
||||
dock(S, TRUE)
|
||||
@@ -259,7 +259,7 @@
|
||||
continue
|
||||
if(isbrain(player)) //also technically dead
|
||||
continue
|
||||
if(get_area(player) == areaInstance)
|
||||
if(shuttle_areas[get_area(player)])
|
||||
has_people = TRUE
|
||||
var/location = get_turf(player.mind.current)
|
||||
if(!(player.mind.special_role == "traitor" || player.mind.special_role == "Syndicate") && !istype(location, /turf/open/floor/plasteel/shuttle/red) && !istype(location, /turf/open/floor/mineral/plastitanium/brig))
|
||||
@@ -369,13 +369,20 @@
|
||||
for(var/area/shuttle/escape/E in GLOB.sortedAreas)
|
||||
areas += E
|
||||
hyperspace_sound(HYPERSPACE_END, areas)
|
||||
if(areaInstance.parallax_movedir && time_left <= PARALLAX_LOOP_TIME)
|
||||
parallax_slowdown()
|
||||
for(var/A in SSshuttle.mobile)
|
||||
var/obj/docking_port/mobile/M = A
|
||||
if(M.launch_status == ENDGAME_LAUNCHED)
|
||||
if(istype(M, /obj/docking_port/mobile/pod))
|
||||
M.parallax_slowdown()
|
||||
if(time_left <= PARALLAX_LOOP_TIME)
|
||||
var/area_parallax = FALSE
|
||||
for(var/place in shuttle_areas)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
if(shuttle_area.parallax_movedir)
|
||||
area_parallax = TRUE
|
||||
break
|
||||
if(area_parallax)
|
||||
parallax_slowdown()
|
||||
for(var/A in SSshuttle.mobile)
|
||||
var/obj/docking_port/mobile/M = A
|
||||
if(M.launch_status == ENDGAME_LAUNCHED)
|
||||
if(istype(M, /obj/docking_port/mobile/pod))
|
||||
M.parallax_slowdown()
|
||||
|
||||
if(time_left <= 0)
|
||||
//move each escape pod to its corresponding escape dock
|
||||
@@ -531,12 +538,6 @@
|
||||
/obj/item/weapon/storage/pod/attack_hand(mob/user)
|
||||
return MouseDrop(user)
|
||||
|
||||
/obj/item/weapon/storage/pod/onShuttleMove()
|
||||
unlocked = TRUE
|
||||
// If the pod was launched, the storage will always open.
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/docking_port/mobile/emergency/backup
|
||||
name = "backup shuttle"
|
||||
id = "backup"
|
||||
|
||||
+351
-50
@@ -1,64 +1,133 @@
|
||||
// Called before shuttle starts moving atoms.
|
||||
/atom/movable/proc/beforeShuttleMove(turf/T1, rotation)
|
||||
return
|
||||
/*
|
||||
All ShuttleMove procs go here
|
||||
*/
|
||||
|
||||
/************************************Base procs************************************/
|
||||
|
||||
// Called on every turf in the shuttle region, return false if it doesn't want to move
|
||||
/turf/proc/fromShuttleMove(turf/newT, turf_type, baseturf_type)
|
||||
if(type == turf_type && baseturf == baseturf_type)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
// Called from the new turf before anything has been moved
|
||||
// Only gets called if fromShuttleMove returns true first
|
||||
/turf/proc/toShuttleMove(turf/oldT, shuttle_dir)
|
||||
for(var/i in 1 to contents.len)
|
||||
var/atom/movable/thing = contents[i]
|
||||
if(ismob(thing))
|
||||
if(isliving(thing))
|
||||
var/mob/living/M = thing
|
||||
if(M.buckled)
|
||||
M.buckled.unbuckle_mob(M, 1)
|
||||
if(M.pulledby)
|
||||
M.pulledby.stop_pulling()
|
||||
M.stop_pulling()
|
||||
M.visible_message("<span class='warning'>[src] slams into [M]!</span>")
|
||||
if(M.key || M.get_ghost(TRUE))
|
||||
SSblackbox.add_details("shuttle_gib", "[type]")
|
||||
else
|
||||
SSblackbox.add_details("shuttle_gib_unintelligent", "[type]")
|
||||
M.gib()
|
||||
|
||||
else //non-living mobs shouldn't be affected by shuttles, which is why this is an else
|
||||
if(istype(thing, /obj/singularity) && !istype(thing, /obj/singularity/narsie)) //it's a singularity but not a god, ignore it.
|
||||
continue
|
||||
if(!thing.anchored)
|
||||
step(thing, shuttle_dir)
|
||||
else
|
||||
qdel(thing)
|
||||
|
||||
return TRUE
|
||||
|
||||
// Called on the old turf to move the turf data
|
||||
/turf/proc/onShuttleMove(turf/newT, turf_type, baseturf_type, rotation, list/movement_force, move_dir)
|
||||
if(newT == src) // In case of in place shuttle rotation shenanigans.
|
||||
return
|
||||
|
||||
//Destination turf changes
|
||||
var/destination_turf_type = newT.type
|
||||
copyTurf(newT)
|
||||
newT.baseturf = destination_turf_type
|
||||
|
||||
if(isopenturf(newT))
|
||||
var/turf/open/new_open = newT
|
||||
new_open.copy_air_with_tile(src)
|
||||
|
||||
//Source turf changes
|
||||
ChangeTurf(turf_type, FALSE, TRUE, baseturf_type)
|
||||
|
||||
return TRUE
|
||||
|
||||
// Called on the new turf after everything has been moved
|
||||
/turf/proc/afterShuttleMove(turf/oldT)
|
||||
if(SSlighting.initialized && FALSE)
|
||||
var/atom/movable/lighting_object/old_obj = lighting_object
|
||||
var/atom/movable/lighting_object/new_obj = oldT.lighting_object
|
||||
if(old_obj)
|
||||
old_obj.update()
|
||||
if(new_obj)
|
||||
new_obj.update()
|
||||
return TRUE
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Called on every atom in shuttle turf contents before anything has been moved
|
||||
// Return true if it should be moved regardless of turf being moved
|
||||
/atom/movable/proc/beforeShuttleMove(turf/newT, rotation)
|
||||
return FALSE
|
||||
|
||||
// Called on atoms to move the atom to the new location
|
||||
/atom/movable/proc/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir)
|
||||
if(newT == oldT) // In case of in place shuttle rotation shenanigans.
|
||||
return
|
||||
|
||||
if(locs && locs.len > 1) // This is for multi tile objects
|
||||
if(loc != oldT)
|
||||
return
|
||||
|
||||
// Called when shuttle attempts to move an atom.
|
||||
/atom/movable/proc/onShuttleMove(turf/T1, rotation, knockdown = TRUE)
|
||||
if(rotation)
|
||||
shuttleRotate(rotation)
|
||||
loc = T1
|
||||
if (length(client_mobs_in_contents))
|
||||
loc = newT
|
||||
if(length(client_mobs_in_contents))
|
||||
update_parallax_contents()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
// Called after all of the atoms on shuttle are moved.
|
||||
/atom/movable/proc/afterShuttleMove()
|
||||
return
|
||||
// Called on atoms after everything has been moved
|
||||
/atom/movable/proc/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir)
|
||||
if(light)
|
||||
update_light()
|
||||
return TRUE
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/onShuttleMove()
|
||||
if(invisibility >= INVISIBILITY_ABSTRACT)
|
||||
return 0
|
||||
. = ..()
|
||||
// Called on areas before anything has been moved
|
||||
/area/proc/beforeShuttleMove()
|
||||
return TRUE
|
||||
|
||||
|
||||
/atom/movable/light/onShuttleMove()
|
||||
return 0
|
||||
|
||||
/obj/machinery/door/airlock/onShuttleMove()
|
||||
shuttledocked = 0
|
||||
for(var/obj/machinery/door/airlock/A in range(1, src))
|
||||
A.shuttledocked = 0
|
||||
A.air_tight = TRUE
|
||||
INVOKE_ASYNC(A, /obj/machinery/door/.proc/close)
|
||||
. = ..()
|
||||
shuttledocked = 1
|
||||
for(var/obj/machinery/door/airlock/A in range(1, src))
|
||||
A.shuttledocked = 1
|
||||
/mob/onShuttleMove()
|
||||
if(!move_on_shuttle)
|
||||
return 0
|
||||
. = ..()
|
||||
if(!.)
|
||||
// Called on areas to move their turf between areas
|
||||
/area/proc/onShuttleMove(turf/oldT, turf/newT, area/underlying_old_area)
|
||||
if(newT == oldT) // In case of in place shuttle rotation shenanigans.
|
||||
return
|
||||
if(client)
|
||||
if(buckled)
|
||||
shake_camera(src, 2, 1) // turn it down a bit come on
|
||||
else
|
||||
shake_camera(src, 7, 1)
|
||||
|
||||
/mob/living/carbon/onShuttleMove(turf/T1, rotation, knockdown = TRUE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!buckled && knockdown)
|
||||
Knockdown(60)
|
||||
contents -= oldT
|
||||
underlying_old_area.contents += oldT
|
||||
oldT.change_area(src, underlying_old_area)
|
||||
//The old turf has now been given back to the area that turf originaly belonged to
|
||||
|
||||
/obj/effect/abstract/proximity_checker/onShuttleMove()
|
||||
//timer so it only happens once
|
||||
addtimer(CALLBACK(monitor, /datum/proximity_monitor/proc/SetRange, monitor.current_range, TRUE), 0, TIMER_UNIQUE)
|
||||
var/area/old_dest_area = newT.loc
|
||||
parallax_movedir = old_dest_area.parallax_movedir
|
||||
|
||||
old_dest_area.contents -= newT
|
||||
contents += newT
|
||||
newT.change_area(old_dest_area, src)
|
||||
return TRUE
|
||||
|
||||
// Shuttle Rotation //
|
||||
// Called on areas after everything has been moved
|
||||
/area/proc/afterShuttleMove()
|
||||
return TRUE
|
||||
|
||||
/************************************Shuttle Rotation************************************/
|
||||
|
||||
/atom/proc/shuttleRotate(rotation)
|
||||
//rotate our direction
|
||||
@@ -76,4 +145,236 @@
|
||||
var/oldPX = pixel_x
|
||||
var/oldPY = pixel_y
|
||||
pixel_x = oldPY
|
||||
pixel_y = (oldPX*(-1))
|
||||
pixel_y = (oldPX*(-1))
|
||||
|
||||
/************************************Turf move procs************************************/
|
||||
|
||||
/turf/open/afterShuttleMove(turf/oldT) //Recalculates SSair stuff for turfs on both sides
|
||||
. = ..()
|
||||
SSair.remove_from_active(src)
|
||||
SSair.remove_from_active(oldT)
|
||||
|
||||
src.CalculateAdjacentTurfs()
|
||||
oldT.CalculateAdjacentTurfs()
|
||||
|
||||
SSair.add_to_active(src, TRUE)
|
||||
SSair.add_to_active(oldT, TRUE)
|
||||
|
||||
/************************************Machinery move procs************************************/
|
||||
|
||||
/obj/machinery/door/airlock/beforeShuttleMove()
|
||||
. = ..()
|
||||
shuttledocked = 0
|
||||
for(var/obj/machinery/door/airlock/A in range(1, src))
|
||||
A.shuttledocked = 0
|
||||
A.air_tight = TRUE
|
||||
INVOKE_ASYNC(A, /obj/machinery/door/.proc/close)
|
||||
|
||||
/obj/machinery/door/airlock/afterShuttleMove()
|
||||
. = ..()
|
||||
shuttledocked = 1
|
||||
for(var/obj/machinery/door/airlock/A in range(1, src))
|
||||
A.shuttledocked = 1
|
||||
|
||||
/obj/machinery/camera/beforeShuttleMove()
|
||||
. = ..()
|
||||
GLOB.cameranet.removeCamera(src)
|
||||
GLOB.cameranet.updateChunk()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/camera/afterShuttleMove()
|
||||
. = ..()
|
||||
if(can_use())
|
||||
GLOB.cameranet.addCamera(src)
|
||||
var/datum/camerachunk/chunk = GLOB.cameranet.getCameraChunk(x, y, z)
|
||||
chunk.hasChanged(TRUE)
|
||||
|
||||
/obj/machinery/telecomms/onShuttleMove(turf/T1)
|
||||
. = ..()
|
||||
if(. && T1) // Update listening Z, just in case you have telecomm relay on a shuttle
|
||||
listening_level = T1.z
|
||||
|
||||
/obj/machinery/mech_bay_recharge_port/afterShuttleMove()
|
||||
. = ..()
|
||||
recharging_turf = get_step(loc, dir)
|
||||
|
||||
/obj/machinery/atmospherics/afterShuttleMove()
|
||||
. = ..()
|
||||
if(pipe_vision_img)
|
||||
pipe_vision_img.loc = loc
|
||||
|
||||
/obj/machinery/computer/auxillary_base/onShuttleMove(turf/T1)
|
||||
. = ..()
|
||||
if(z == ZLEVEL_MINING) //Avoids double logging and landing on other Z-levels due to badminnery
|
||||
SSblackbox.add_details("colonies_dropped", "[x]|[y]|[z]") //Number of times a base has been dropped!
|
||||
|
||||
/obj/machinery/gravity_generator/main/beforeShuttleMove()
|
||||
. = ..()
|
||||
on = FALSE
|
||||
update_list()
|
||||
|
||||
/obj/machinery/gravity_generator/main/afterShuttleMove()
|
||||
. = ..()
|
||||
if(charge_count != 0 && charging_state != POWER_UP)
|
||||
on = TRUE
|
||||
update_list()
|
||||
|
||||
/obj/machinery/thruster/beforeShuttleMove()
|
||||
. = ..()
|
||||
. = TRUE
|
||||
|
||||
//Properly updates pipes on shuttle movement
|
||||
/obj/machinery/atmospherics/shuttleRotate(rotation)
|
||||
var/list/real_node_connect = getNodeConnects()
|
||||
for(DEVICE_TYPE_LOOP)
|
||||
real_node_connect[I] = angle2dir(rotation+dir2angle(real_node_connect[I]))
|
||||
|
||||
. = ..()
|
||||
SetInitDirections()
|
||||
var/list/supposed_node_connect = getNodeConnects()
|
||||
var/list/nodes_copy = nodes.Copy()
|
||||
|
||||
for(DEVICE_TYPE_LOOP)
|
||||
var/new_pos = supposed_node_connect.Find(real_node_connect[I])
|
||||
nodes[new_pos] = nodes_copy[I]
|
||||
|
||||
/obj/machinery/atmospherics/afterShuttleMove()
|
||||
. = ..()
|
||||
var/missing_nodes = FALSE
|
||||
for(DEVICE_TYPE_LOOP)
|
||||
if(src.nodes[I])
|
||||
var/obj/machinery/atmospherics/node = src.nodes[I]
|
||||
var/connected = FALSE
|
||||
for(var/D in GLOB.cardinals)
|
||||
if(node in get_step(src, D))
|
||||
connected = TRUE
|
||||
break
|
||||
|
||||
if(!connected)
|
||||
nullifyNode(I)
|
||||
|
||||
if(!src.nodes[I])
|
||||
missing_nodes = TRUE
|
||||
|
||||
if(missing_nodes)
|
||||
atmosinit()
|
||||
for(var/obj/machinery/atmospherics/A in pipeline_expansion())
|
||||
A.atmosinit()
|
||||
if(A.returnPipenet())
|
||||
A.addMember(src)
|
||||
build_network()
|
||||
else
|
||||
// atmosinit() calls update_icon(), so we don't need to call it
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/afterShuttleMove()
|
||||
. = ..()
|
||||
var/turf/T = loc
|
||||
hide(T.intact)
|
||||
|
||||
/obj/machinery/navbeacon/beforeShuttleMove()
|
||||
. = ..()
|
||||
GLOB.navbeacons["[z]"] -= src
|
||||
GLOB.deliverybeacons -= src
|
||||
|
||||
/obj/machinery/navbeacon/afterShuttleMove()
|
||||
. = ..()
|
||||
var/turf/T = loc
|
||||
hide(T.intact)
|
||||
if(codes["patrol"])
|
||||
if(!GLOB.navbeacons["[z]"])
|
||||
GLOB.navbeacons["[z]"] = list()
|
||||
GLOB.navbeacons["[z]"] += src //Register with the patrol list!
|
||||
if(codes["delivery"])
|
||||
GLOB.deliverybeacons += src
|
||||
GLOB.deliverybeacontags += location
|
||||
|
||||
/obj/machinery/power/terminal/afterShuttleMove()
|
||||
. = ..()
|
||||
var/turf/T = src.loc
|
||||
if(level==1)
|
||||
hide(T.intact)
|
||||
|
||||
/************************************Item move procs************************************/
|
||||
|
||||
/obj/item/weapon/storage/pod/onShuttleMove()
|
||||
unlocked = TRUE
|
||||
// If the pod was launched, the storage will always open.
|
||||
return ..()
|
||||
|
||||
/************************************Mob move procs************************************/
|
||||
|
||||
/mob/onShuttleMove()
|
||||
if(!move_on_shuttle)
|
||||
return 0
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(client)
|
||||
if(buckled)
|
||||
shake_camera(src, 2, 1) // turn it down a bit come on
|
||||
else
|
||||
shake_camera(src, 7, 1)
|
||||
|
||||
/mob/living/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir)
|
||||
. = ..()
|
||||
if(movement_force && !buckled)
|
||||
if(movement_force["THROW"])
|
||||
var/throw_dir = move_dir
|
||||
var/turf/target = get_edge_target_turf(src, throw_dir)
|
||||
var/range = movement_force["THROW"]
|
||||
var/speed = range/5
|
||||
src.throw_at(target, range, speed)
|
||||
if(movement_force["KNOCKDOWN"])
|
||||
Knockdown(movement_force["KNOCKDOWN"])
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/onShuttleMove()
|
||||
var/turf/oldT = loc
|
||||
. = ..()
|
||||
message_admins("Megafauna [src] [ADMIN_FLW(src)] moved via shuttle from [ADMIN_COORDJMP(oldT)] to [ADMIN_COORDJMP(loc)]")
|
||||
|
||||
/************************************Structure move procs************************************/
|
||||
|
||||
/obj/structure/grille/beforeShuttleMove()
|
||||
. = ..()
|
||||
. = TRUE
|
||||
|
||||
/obj/structure/lattice/beforeShuttleMove()
|
||||
. = ..()
|
||||
. = TRUE
|
||||
|
||||
/obj/structure/disposalpipe/afterShuttleMove()
|
||||
. = ..()
|
||||
update()
|
||||
|
||||
/obj/structure/cable/afterShuttleMove()
|
||||
. = ..()
|
||||
var/turf/T = loc
|
||||
if(level==1)
|
||||
hide(T.intact)
|
||||
|
||||
/************************************Misc move procs************************************/
|
||||
|
||||
/atom/movable/lighting_object/onShuttleMove()
|
||||
return FALSE
|
||||
|
||||
/atom/movable/light/onShuttleMove()
|
||||
return FALSE
|
||||
|
||||
/obj/docking_port/stationary/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force)
|
||||
var/obj/docking_port/mobile/docked_port = get_docked()
|
||||
if(!docked_port)
|
||||
docked_port = locate(/obj/docking_port/mobile) in newT
|
||||
|
||||
if(docked_port && locate(/obj/docking_port/stationary) in newT)
|
||||
return FALSE //There's a mobile dock that's moving to the new turf to be with another stationary dock! After all I did for them...
|
||||
|
||||
. = ..()
|
||||
|
||||
obj/docking_port/stationary/public_mining_dock/onShuttleMove()
|
||||
id = "mining_public" //It will not move with the base, but will become enabled as a docking point.
|
||||
return 0
|
||||
|
||||
/obj/effect/abstract/proximity_checker/onShuttleMove()
|
||||
//timer so it only happens once
|
||||
addtimer(CALLBACK(monitor, /datum/proximity_monitor/proc/SetRange, monitor.current_range, TRUE), 0, TIMER_UNIQUE)
|
||||
|
||||
+176
-172
@@ -74,7 +74,7 @@
|
||||
|
||||
//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
|
||||
/obj/docking_port/proc/return_ordered_turfs(_x, _y, _z, _dir, area/A)
|
||||
/obj/docking_port/proc/return_ordered_turfs(_x, _y, _z, _dir, area_type)
|
||||
if(!_dir)
|
||||
_dir = dir
|
||||
if(!_x)
|
||||
@@ -105,8 +105,8 @@
|
||||
xi = _x + (dx-dwidth)*cos - (dy-dheight)*sin
|
||||
yi = _y + (dy-dheight)*cos + (dx-dwidth)*sin
|
||||
var/turf/T = locate(xi, yi, _z)
|
||||
if(A)
|
||||
if(get_area(T) == A)
|
||||
if(area_type)
|
||||
if(istype(get_area(T), area_type))
|
||||
. += T
|
||||
else
|
||||
. += null
|
||||
@@ -142,6 +142,7 @@
|
||||
name = "dock"
|
||||
|
||||
var/turf_type = /turf/open/space
|
||||
var/baseturf_type = /turf/open/space
|
||||
var/area_type = /area/space
|
||||
var/last_dock_time
|
||||
|
||||
@@ -173,14 +174,16 @@
|
||||
SSshuttle.transit += src
|
||||
|
||||
/obj/docking_port/stationary/transit/proc/dezone()
|
||||
for(var/i in assigned_turfs)
|
||||
var/turf/T = i
|
||||
for(var/i in 1 to assigned_turfs.len)
|
||||
var/turf/T = assigned_turfs[i]
|
||||
if(T.type == turf_type)
|
||||
T.ChangeTurf(/turf/open/space)
|
||||
T.ChangeTurf(/turf/open/space,new_baseturf=/turf/open/space)
|
||||
T.flags |= UNUSED_TRANSIT_TURF
|
||||
|
||||
/obj/docking_port/stationary/transit/Destroy(force=FALSE)
|
||||
if(force)
|
||||
if(get_docked())
|
||||
to_chat("A transit dock was destroyed while something was docked to it.")
|
||||
SSshuttle.transit -= src
|
||||
if(owner)
|
||||
owner = null
|
||||
@@ -195,7 +198,8 @@
|
||||
name = "shuttle"
|
||||
icon_state = "pinonclose"
|
||||
|
||||
var/area/shuttle/areaInstance
|
||||
var/area_type = /area/shuttle
|
||||
var/list/area/shuttle/shuttle_areas
|
||||
|
||||
var/timer //used as a timer (if you want time left to complete move, use timeLeft proc)
|
||||
var/last_timer_length
|
||||
@@ -217,7 +221,7 @@
|
||||
|
||||
var/launch_status = NOLAUNCH
|
||||
|
||||
var/knockdown = TRUE //Will it knock down mobs when it docks?
|
||||
var/list/movement_force = list("KNOCKDOWN" = 3, "THROW" = 0)
|
||||
|
||||
// A timid shuttle will not register itself with the shuttle subsystem
|
||||
// All shuttle templates are timid
|
||||
@@ -237,7 +241,7 @@
|
||||
destination = null
|
||||
previous = null
|
||||
assigned_transit = null
|
||||
areaInstance = null
|
||||
shuttle_areas = null
|
||||
. = ..()
|
||||
|
||||
/obj/docking_port/mobile/Initialize(mapload)
|
||||
@@ -245,19 +249,18 @@
|
||||
if(!timid)
|
||||
register()
|
||||
|
||||
var/area/A = get_area(src)
|
||||
if(istype(A, /area/shuttle))
|
||||
areaInstance = A
|
||||
|
||||
if(!id)
|
||||
id = "[SSshuttle.mobile.len]"
|
||||
if(name == "shuttle")
|
||||
name = "shuttle[SSshuttle.mobile.len]"
|
||||
|
||||
if(!areaInstance)
|
||||
areaInstance = new()
|
||||
areaInstance.name = name
|
||||
areaInstance.contents += return_ordered_turfs()
|
||||
shuttle_areas = list()
|
||||
var/list/all_turfs = return_ordered_turfs(x, y, z, dir)
|
||||
for(var/i in 1 to all_turfs.len)
|
||||
var/turf/curT = all_turfs[i]
|
||||
var/area/cur_area = curT.loc
|
||||
if(istype(cur_area, area_type))
|
||||
shuttle_areas[cur_area] = TRUE
|
||||
|
||||
initial_engines = count_engines()
|
||||
current_engines = initial_engines
|
||||
@@ -378,32 +381,41 @@
|
||||
/obj/docking_port/mobile/proc/jumpToNullSpace()
|
||||
// Destroys the docking port and the shuttle contents.
|
||||
// Not in a fancy way, it just ceases.
|
||||
var/obj/docking_port/stationary/S0 = get_docked()
|
||||
var/obj/docking_port/stationary/current_dock = get_docked()
|
||||
|
||||
var/turf_type = /turf/open/space
|
||||
var/baseturf_type = /turf/open/space
|
||||
var/area_type = /area/space
|
||||
// If the shuttle is docked to a stationary port, restore its normal
|
||||
// "empty" area and turf
|
||||
if(S0)
|
||||
if(S0.turf_type)
|
||||
turf_type = S0.turf_type
|
||||
if(S0.area_type)
|
||||
area_type = S0.area_type
|
||||
if(current_dock)
|
||||
if(current_dock.turf_type)
|
||||
turf_type = current_dock.turf_type
|
||||
if(current_dock.baseturf_type)
|
||||
baseturf_type = current_dock.baseturf_type
|
||||
if(current_dock.area_type)
|
||||
area_type = current_dock.area_type
|
||||
|
||||
var/list/L0 = return_ordered_turfs(x, y, z, dir, areaInstance)
|
||||
var/list/shuttle_turfs = return_ordered_turfs(x, y, z, dir, area_type)
|
||||
|
||||
//remove area surrounding docking port
|
||||
if(areaInstance.contents.len)
|
||||
var/area/A0 = locate("[area_type]")
|
||||
if(!A0)
|
||||
A0 = new area_type(null)
|
||||
for(var/turf/T0 in L0)
|
||||
A0.contents += T0
|
||||
for(var/i in 1 to shuttle_areas.len)
|
||||
var/area/shuttle_area = shuttle_areas[i]
|
||||
if(shuttle_area.contents.len)
|
||||
var/area/underlying_area = locate("[area_type]")
|
||||
if(!underlying_area)
|
||||
underlying_area = new area_type(null)
|
||||
for(var/ii in shuttle_turfs)
|
||||
var/turf/T = shuttle_turfs[ii]
|
||||
var/area/old_area = T.loc
|
||||
underlying_area.contents += T
|
||||
T.change_area(old_area, underlying_area)
|
||||
|
||||
for(var/i in L0)
|
||||
var/turf/T0 =i
|
||||
if(!T0)
|
||||
for(var/i in shuttle_turfs)
|
||||
var/turf/T = i
|
||||
if(!T)
|
||||
continue
|
||||
T0.empty(turf_type)
|
||||
T.empty(turf_type, baseturf_type)
|
||||
|
||||
qdel(src, force=TRUE)
|
||||
|
||||
@@ -418,7 +430,7 @@
|
||||
ripples.Cut()
|
||||
|
||||
/obj/docking_port/mobile/proc/ripple_area(obj/docking_port/stationary/S1)
|
||||
var/list/L0 = return_ordered_turfs(x, y, z, dir, areaInstance)
|
||||
var/list/L0 = return_ordered_turfs(x, y, z, dir, area_type)
|
||||
var/list/L1 = return_ordered_turfs(S1.x, S1.y, S1.z, S1.dir)
|
||||
|
||||
var/list/ripple_turfs = list()
|
||||
@@ -439,117 +451,134 @@
|
||||
for(var/obj/machinery/door/poddoor/shuttledock/pod in GLOB.airlocks)
|
||||
pod.check()
|
||||
|
||||
//this is the main proc. It instantly moves our mobile port to stationary port S1
|
||||
//it handles all the generic behaviour, such as sanity checks, closing doors on the shuttle, stunning mobs, etc
|
||||
/obj/docking_port/mobile/proc/dock(obj/docking_port/stationary/S1, force=FALSE)
|
||||
if(S1.get_docked() == src)
|
||||
remove_ripples()
|
||||
return
|
||||
//this is the main proc. It instantly moves our mobile port to stationary port new_dock
|
||||
/obj/docking_port/mobile/proc/dock(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
|
||||
// Crashing this ship with NO SURVIVORS
|
||||
|
||||
if(new_dock.get_docked() == src)
|
||||
remove_ripples()
|
||||
return DOCKING_COMPLETE
|
||||
|
||||
if(!force)
|
||||
if(!check_dock(S1))
|
||||
return -1
|
||||
if(!check_dock(new_dock))
|
||||
return DOCKING_BLOCKED
|
||||
if(!canMove())
|
||||
return -1
|
||||
return DOCKING_IMMOBILIZED
|
||||
|
||||
var/obj/docking_port/stationary/S0 = get_docked()
|
||||
var/turf_type = /turf/open/space
|
||||
var/area_type = /area/space
|
||||
if(S0)
|
||||
if(S0.turf_type)
|
||||
turf_type = S0.turf_type
|
||||
if(S0.area_type)
|
||||
area_type = S0.area_type
|
||||
var/obj/docking_port/stationary/old_dock = get_docked()
|
||||
var/turf_type = /turf/open/space //The turf that gets placed under where the shuttle moved from
|
||||
var/baseturf_type = /turf/open/space //The baseturf that the gets assigned to the turf_type above
|
||||
var/area_type = /area/space //The area that gets placed under where the shuttle moved from
|
||||
if(old_dock) //Dock overwrites
|
||||
if(old_dock.turf_type)
|
||||
turf_type = old_dock.turf_type
|
||||
if(old_dock.baseturf_type)
|
||||
baseturf_type = old_dock.baseturf_type
|
||||
if(old_dock.area_type)
|
||||
area_type = old_dock.area_type
|
||||
|
||||
var/destination_turf_type = S1.turf_type
|
||||
var/list/old_turfs = return_ordered_turfs(x, y, z, dir)
|
||||
var/list/new_turfs = return_ordered_turfs(new_dock.x, new_dock.y, new_dock.z, new_dock.dir)
|
||||
var/list/old_contents = list() //Lists of turfs to only move contents and area but not move the turf
|
||||
var/list/new_contents = list() //For structures etc that act attached to the ship
|
||||
|
||||
var/list/L0 = return_ordered_turfs(x, y, z, dir, areaInstance)
|
||||
var/list/L1 = return_ordered_turfs(S1.x, S1.y, S1.z, S1.dir)
|
||||
var/area/underlying_old_area = locate("[area_type]")
|
||||
if(!underlying_old_area)
|
||||
underlying_old_area = new area_type(null)
|
||||
|
||||
var/rotation = dir2angle(S1.dir)-dir2angle(dir)
|
||||
if ((rotation % 90) != 0)
|
||||
rotation += (rotation % 90) //diagonal rotations not allowed, round up
|
||||
rotation = SimplifyDegrees(rotation)
|
||||
var/rotation = 0
|
||||
if(new_dock.dir != dir) //Even when the dirs are the same rotation is coming out as not 0 for some reason
|
||||
rotation = dir2angle(new_dock)-dir2angle(dir)
|
||||
if ((rotation % 90) != 0)
|
||||
rotation += (rotation % 90) //diagonal rotations not allowed, round up
|
||||
rotation = SimplifyDegrees(rotation)
|
||||
|
||||
if(!movement_direction)
|
||||
movement_direction = turn(preferred_direction, 180)
|
||||
|
||||
//remove area surrounding docking port
|
||||
if(areaInstance.contents.len)
|
||||
var/area/A0 = locate("[area_type]")
|
||||
if(!A0)
|
||||
A0 = new area_type(null)
|
||||
for(var/turf/T0 in L0)
|
||||
var/area/old = T0.loc
|
||||
A0.contents += T0
|
||||
T0.change_area(old, A0)
|
||||
if (istype(S1, /obj/docking_port/stationary/transit))
|
||||
areaInstance.parallax_movedir = preferred_direction
|
||||
else
|
||||
areaInstance.parallax_movedir = FALSE
|
||||
remove_ripples()
|
||||
|
||||
//move or squish anything in the way ship at destination
|
||||
roadkill(L0, L1, S1.dir)
|
||||
var/list/moved_atoms = list() //Everything not a turf that gets moved in the shuttle
|
||||
var/list/areas_to_move = list() //unique assoc list of areas on turfs being moved
|
||||
|
||||
|
||||
for(var/i in 1 to L0.len)
|
||||
var/turf/T0 = L0[i]
|
||||
if(!T0)
|
||||
/****************************************All beforeShuttleMove procs*****************************************/
|
||||
var/index = 1
|
||||
while(index <= old_turfs.len)
|
||||
var/turf/oldT = old_turfs[index]
|
||||
var/turf/newT = new_turfs[index]
|
||||
var/area/old_area = oldT.loc
|
||||
var/move_turf = TRUE //Should this turf be moved, if false remove from the turf list
|
||||
if(!(shuttle_areas[old_area]))
|
||||
move_turf = FALSE
|
||||
if(move_turf)
|
||||
move_turf = oldT.fromShuttleMove(newT, turf_type, baseturf_type) //turf
|
||||
if(move_turf) //Only call toShuttleMove if the source turf is willing to move
|
||||
move_turf = newT.toShuttleMove(oldT, dir) //turf
|
||||
for(var/ii in 1 to oldT.contents.len)
|
||||
var/atom/movable/moving_atom = oldT.contents[ii]
|
||||
if(moving_atom.beforeShuttleMove(newT, rotation) && !move_turf) //atoms
|
||||
old_contents += oldT
|
||||
new_contents += newT
|
||||
if(!move_turf)
|
||||
old_turfs.Cut(index,index+1)
|
||||
new_turfs.Cut(index,index+1)
|
||||
continue
|
||||
var/turf/T1 = L1[i]
|
||||
if(!T1)
|
||||
areas_to_move[old_area] = TRUE
|
||||
index++
|
||||
|
||||
for(var/thing in areas_to_move)
|
||||
var/area/internal_area = thing
|
||||
internal_area.beforeShuttleMove() //areas
|
||||
|
||||
if(!old_turfs.len && !old_contents.len) //This should only happen if no shuttle area has been specified
|
||||
return DOCKING_AREA_EMPTY
|
||||
|
||||
/*******************************************All onShuttleMove procs******************************************/
|
||||
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
var/turf/oldT = old_turfs[i]
|
||||
var/turf/newT = new_turfs[i]
|
||||
if(!oldT || !newT) //This really shouldn't happen
|
||||
continue
|
||||
if(T0.type == T0.baseturf)
|
||||
for(var/thing in oldT) //Needs to be this kind of loop in case, because of shuttle rotation shenanigans, the destination turf is the same as the source turf
|
||||
var/atom/movable/moving_atom = thing
|
||||
moving_atom.onShuttleMove(newT, oldT, rotation, movement_force, movement_direction) //atoms
|
||||
moved_atoms += moving_atom
|
||||
oldT.onShuttleMove(newT, turf_type, baseturf_type, rotation, movement_force, movement_direction) //turfs
|
||||
var/area/shuttle_area = oldT.loc
|
||||
shuttle_area.onShuttleMove(oldT, newT, underlying_old_area) //areas
|
||||
|
||||
for(var/i in 1 to old_contents.len) //This is for moving atoms that need to move without their turf
|
||||
var/turf/oldT = old_contents[i] //I'll figure out a way of merging these loops eventualy, probably
|
||||
var/turf/newT = new_contents[i]
|
||||
if(!oldT || !newT)
|
||||
continue
|
||||
for(var/atom/movable/AM in T0)
|
||||
AM.beforeShuttleMove(T1, rotation)
|
||||
for(var/thing in oldT)
|
||||
var/atom/movable/moving_atom = thing
|
||||
moving_atom.onShuttleMove(newT, oldT, rotation, movement_force, movement_direction) //atoms
|
||||
moved_atoms += moving_atom
|
||||
|
||||
/******************************************All afterShuttleMove procs****************************************/
|
||||
|
||||
for(var/i in 1 to new_turfs.len)
|
||||
var/turf/oldT = old_turfs[i]
|
||||
var/turf/newT = new_turfs[i]
|
||||
newT.afterShuttleMove(oldT) //turfs
|
||||
|
||||
var/list/moved_atoms = list()
|
||||
for(var/i in 1 to moved_atoms.len)
|
||||
var/atom/movable/moved_object = moved_atoms[i]
|
||||
moved_object.afterShuttleMove(movement_force, dir, preferred_direction, movement_direction) //atoms
|
||||
|
||||
for(var/i in 1 to L0.len)
|
||||
var/turf/T0 = L0[i]
|
||||
if(!T0)
|
||||
continue
|
||||
var/turf/T1 = L1[i]
|
||||
if(!T1)
|
||||
continue
|
||||
if(T0.type != T0.baseturf) //So if there is a hole in the shuttle we don't drag along the space/asteroid/etc to wherever we are going next
|
||||
T0.copyTurf(T1)
|
||||
T1.baseturf = destination_turf_type
|
||||
var/area/old = T1.loc
|
||||
areaInstance.contents += T1
|
||||
T1.change_area(old, areaInstance)
|
||||
underlying_old_area.afterShuttleMove()
|
||||
|
||||
//copy over air
|
||||
if(isopenturf(T1))
|
||||
var/turf/open/Ts1 = T1
|
||||
Ts1.copy_air_with_tile(T0)
|
||||
for(var/thing in areas_to_move)
|
||||
var/area/internal_area = thing
|
||||
internal_area.afterShuttleMove() //areas
|
||||
|
||||
//move mobile to new location
|
||||
for(var/atom/movable/AM in T0)
|
||||
if(AM.onShuttleMove(T1, rotation, knockdown))
|
||||
moved_atoms += AM
|
||||
new_dock.last_dock_time = world.time
|
||||
setDir(new_dock.dir)
|
||||
|
||||
if(rotation)
|
||||
T1.shuttleRotate(rotation)
|
||||
|
||||
SSair.remove_from_active(T1)
|
||||
T1.CalculateAdjacentTurfs()
|
||||
SSair.add_to_active(T1,1)
|
||||
|
||||
T0.ChangeTurf(turf_type)
|
||||
|
||||
SSair.remove_from_active(T0)
|
||||
T0.CalculateAdjacentTurfs()
|
||||
SSair.add_to_active(T0,1)
|
||||
|
||||
for(var/am in moved_atoms)
|
||||
var/atom/movable/AM = am
|
||||
AM.afterShuttleMove()
|
||||
|
||||
check_poddoors()
|
||||
S1.last_dock_time = world.time
|
||||
|
||||
loc = S1.loc
|
||||
setDir(S1.dir)
|
||||
return DOCKING_SUCCESS
|
||||
|
||||
/obj/docking_port/mobile/proc/findRoundstartDock()
|
||||
return SSshuttle.getDock(roundstart_move)
|
||||
@@ -567,40 +596,6 @@
|
||||
/obj/effect/landmark/shuttle_import
|
||||
name = "Shuttle Import"
|
||||
|
||||
/obj/docking_port/mobile/proc/roadkill(list/L0, list/L1, dir)
|
||||
for(var/i in 1 to L0.len)
|
||||
var/turf/T0 = L0[i]
|
||||
var/turf/T1 = L1[i]
|
||||
if(!T0 || !T1)
|
||||
continue
|
||||
if(T0.type == T0.baseturf)
|
||||
continue
|
||||
// The corresponding tile will not be changed, so no roadkill
|
||||
|
||||
for(var/atom/movable/AM in T1)
|
||||
if(ismob(AM))
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
if(M.buckled)
|
||||
M.buckled.unbuckle_mob(M, 1)
|
||||
if(M.pulledby)
|
||||
M.pulledby.stop_pulling()
|
||||
M.stop_pulling()
|
||||
M.visible_message("<span class='warning'>[src] slams into [M]!</span>")
|
||||
if(M.key || M.get_ghost(TRUE))
|
||||
SSblackbox.add_details("shuttle_gib", "[type]")
|
||||
else
|
||||
SSblackbox.add_details("shuttle_gib_unintelligent", "[type]")
|
||||
M.gib()
|
||||
|
||||
else //non-living mobs shouldn't be affected by shuttles, which is why this is an else
|
||||
if(istype(AM, /obj/singularity) && !istype(AM, /obj/singularity/narsie)) //it's a singularity but not a god, ignore it.
|
||||
continue
|
||||
if(!AM.anchored)
|
||||
step(AM, dir)
|
||||
else
|
||||
qdel(AM)
|
||||
|
||||
//used by shuttle subsystem to check timers
|
||||
/obj/docking_port/mobile/proc/check()
|
||||
check_effects()
|
||||
@@ -614,7 +609,7 @@
|
||||
// then try again
|
||||
switch(mode)
|
||||
if(SHUTTLE_CALL)
|
||||
if(dock(destination))
|
||||
if(dock(destination, preferred_direction))
|
||||
setTimer(20)
|
||||
return
|
||||
if(SHUTTLE_RECALL)
|
||||
@@ -643,14 +638,19 @@
|
||||
create_ripples(destination, tl)
|
||||
|
||||
var/obj/docking_port/stationary/S0 = get_docked()
|
||||
if(areaInstance.parallax_movedir && istype(S0, /obj/docking_port/stationary/transit) && timeLeft(1) <= PARALLAX_LOOP_TIME)
|
||||
parallax_slowdown()
|
||||
if(istype(S0, /obj/docking_port/stationary/transit) && timeLeft(1) <= PARALLAX_LOOP_TIME)
|
||||
for(var/place in shuttle_areas)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
if(shuttle_area.parallax_movedir)
|
||||
parallax_slowdown()
|
||||
|
||||
/obj/docking_port/mobile/proc/parallax_slowdown()
|
||||
areaInstance.parallax_movedir = FALSE
|
||||
for(var/place in shuttle_areas)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
shuttle_area.parallax_movedir = FALSE
|
||||
if(assigned_transit && assigned_transit.assigned_area)
|
||||
assigned_transit.assigned_area.parallax_movedir = FALSE
|
||||
var/list/L0 = return_ordered_turfs(x, y, z, dir, areaInstance)
|
||||
var/list/L0 = return_ordered_turfs(x, y, z, dir, area_type)
|
||||
for (var/thing in L0)
|
||||
var/turf/T = thing
|
||||
for (var/thing2 in T)
|
||||
@@ -740,9 +740,11 @@
|
||||
|
||||
// attempts to locate /obj/machinery/computer/shuttle with matching ID inside the shuttle
|
||||
/obj/docking_port/mobile/proc/getControlConsole()
|
||||
for(var/obj/machinery/computer/shuttle/S in areaInstance)
|
||||
if(S.shuttleId == id)
|
||||
return S
|
||||
for(var/place in shuttle_areas)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
for(var/obj/machinery/computer/shuttle/S in shuttle_area)
|
||||
if(S.shuttleId == id)
|
||||
return S
|
||||
return null
|
||||
|
||||
/obj/docking_port/mobile/proc/hyperspace_sound(phase, list/areas)
|
||||
@@ -785,9 +787,11 @@
|
||||
|
||||
/obj/docking_port/mobile/proc/count_engines()
|
||||
. = 0
|
||||
for(var/obj/structure/shuttle/engine/E in areaInstance.contents)
|
||||
if(!QDELETED(E))
|
||||
. += E.engine_power
|
||||
for(var/thing in shuttle_areas)
|
||||
var/area/shuttle/areaInstance = thing
|
||||
for(var/obj/structure/shuttle/engine/E in areaInstance.contents)
|
||||
if(!QDELETED(E))
|
||||
. += E.engine_power
|
||||
|
||||
// Double initial engines to get to 0.5 minimum
|
||||
// Lose all initial engines to get to 2
|
||||
|
||||
@@ -41,15 +41,17 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
|
||||
/obj/docking_port/mobile/supply/canMove()
|
||||
if(z == ZLEVEL_STATION)
|
||||
return check_blacklist(areaInstance)
|
||||
return check_blacklist(shuttle_areas)
|
||||
return ..()
|
||||
|
||||
/obj/docking_port/mobile/supply/proc/check_blacklist(areaInstance)
|
||||
for(var/trf in areaInstance)
|
||||
var/turf/T = trf
|
||||
for(var/a in T.GetAllContents())
|
||||
if(is_type_in_typecache(a, GLOB.blacklisted_cargo_types))
|
||||
return FALSE
|
||||
/obj/docking_port/mobile/supply/proc/check_blacklist(areaInstances)
|
||||
for(var/place in areaInstances)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
for(var/trf in shuttle_area)
|
||||
var/turf/T = trf
|
||||
for(var/a in T.GetAllContents())
|
||||
if(is_type_in_typecache(a, GLOB.blacklisted_cargo_types))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/docking_port/mobile/supply/request()
|
||||
@@ -70,10 +72,12 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
return
|
||||
|
||||
var/list/empty_turfs = list()
|
||||
for(var/turf/open/floor/T in areaInstance)
|
||||
if(is_blocked_turf(T))
|
||||
continue
|
||||
empty_turfs += T
|
||||
for(var/place in shuttle_areas)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
for(var/turf/open/floor/T in shuttle_area)
|
||||
if(is_blocked_turf(T))
|
||||
continue
|
||||
empty_turfs += T
|
||||
|
||||
var/value = 0
|
||||
var/purchases = 0
|
||||
@@ -107,10 +111,12 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
var/msg = ""
|
||||
var/sold_atoms = ""
|
||||
|
||||
for(var/atom/movable/AM in areaInstance)
|
||||
if(AM.anchored && !istype(AM, /obj/mecha))
|
||||
continue
|
||||
sold_atoms += export_item_and_contents(AM, contraband, emagged, dry_run = FALSE)
|
||||
for(var/place in shuttle_areas)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
for(var/atom/movable/AM in shuttle_area)
|
||||
if(AM.anchored)
|
||||
continue
|
||||
sold_atoms += export_item_and_contents(AM, contraband, emagged, dry_run = FALSE)
|
||||
|
||||
if(sold_atoms)
|
||||
sold_atoms += "."
|
||||
|
||||
Reference in New Issue
Block a user