Files
Bubberstation/code/modules/shuttle/on_move.dm
Rob Bailey 65e9888fa6 [READY] Smart Cables (#44265)
Cables now autoconnect on cardinal directions. All cable placement has been completely stripped out and replaced with simple single cable per tile logic.
Low effort demo: https://www.youtube.com/watch?v=fXp8s6ORWbA
Yes I am aware that cutting it is not dropping wire, that version was bugged.
Cables no longer need a knot specifically placed to link to power objects. The sprite is automatically changed to represent this.
The only exception to this logic is that on smes units, due to the terminal being next to the output, they will not link there.
On a technical powernet side, this is the same as old cables once actually placed. They still use the existing powernet system, just the placement and connection works differently.

Old cables have been turned into "pipe cleaners" for wire art purposes. they work just like the old ones, just missing all the powernet functionality, and also you can put them on top of the floor.
Why It's Good For The Game

How obnoxious cables were to both map and work with in game has been something that has annoyed me for a really long time now.
This is both easier for new players to learn, and easier for experienced players to work with.
Along with making in game much more intuitive and easier, it makes mapping much easier as well. Mad lad wjohn was able to rip out all the mapping conversion in one day because of how much faster it is to work with.

cl actioninja and wjohn
add: Cables have been completely reworked. Simple per tile connection logic, automatically connects to things above it. Think minecraft redstone.
add: Old cables have been kept as pipe cleaner. They are non-functional in terms of power, but otherwise have the same connection logic. Also can go on top of tiles.
remove: mech cable layer has been removed because it was terrible shitcode nobody used
tweak: (sort of balance) cable stack sized has been reduced to 15.
/cl
2019-06-22 10:24:37 +12:00

397 lines
14 KiB
Plaintext

/*
All ShuttleMove procs go here
*/
/************************************Base procs************************************/
// Called on every turf in the shuttle region, returns a bitflag for allowed movements of that turf
// returns the new move_mode (based on the old)
/turf/proc/fromShuttleMove(turf/newT, move_mode)
if(!(move_mode & MOVE_AREA) || !isshuttleturf(src))
return move_mode
return move_mode | MOVE_TURF | MOVE_CONTENTS
// Called from the new turf before anything has been moved
// Only gets called if fromShuttleMove returns true first
// returns the new move_mode (based on the old)
/turf/proc/toShuttleMove(turf/oldT, move_mode, obj/docking_port/mobile/shuttle)
. = move_mode
if(!(. & MOVE_TURF))
return
var/shuttle_dir = shuttle.dir
for(var/i in contents)
var/atom/movable/thing = 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'>[shuttle] slams into [M]!</span>")
SSblackbox.record_feedback("tally", "shuttle_gib", 1, M.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)
// Called on the old turf to move the turf data
/turf/proc/onShuttleMove(turf/newT, list/movement_force, move_dir)
if(newT == src) // In case of in place shuttle rotation shenanigans.
return
//Destination turf changes
//Baseturfs is definitely a list or this proc wouldnt be called
var/shuttle_boundary = baseturfs.Find(/turf/baseturf_skipover/shuttle)
if(!shuttle_boundary)
CRASH("A turf queued to move via shuttle somehow had no skipover in baseturfs. [src]([type]):[loc]")
var/depth = baseturfs.len - shuttle_boundary + 1
newT.CopyOnTop(src, 1, depth, TRUE)
//Air stuff
newT.blocks_air = TRUE
newT.air_update_turf(TRUE)
blocks_air = TRUE
air_update_turf(TRUE)
if(isopenturf(newT))
var/turf/open/new_open = newT
new_open.copy_air_with_tile(src)
return TRUE
// Called on the new turf after everything has been moved
/turf/proc/afterShuttleMove(turf/oldT, rotation)
//Dealing with the turf we left behind
oldT.TransferComponents(src)
var/shuttle_boundary = baseturfs.Find(/turf/baseturf_skipover/shuttle)
if(shuttle_boundary)
oldT.ScrapeAway(baseturfs.len - shuttle_boundary + 1)
if(rotation)
shuttleRotate(rotation) //see shuttle_rotate.dm
return TRUE
/turf/proc/lateShuttleMove(turf/oldT)
blocks_air = initial(blocks_air)
air_update_turf(TRUE)
oldT.blocks_air = initial(oldT.blocks_air)
oldT.air_update_turf(TRUE)
/////////////////////////////////////////////////////////////////////////////////////
// Called on every atom in shuttle turf contents before anything has been moved
// returns the new move_mode (based on the old)
// WARNING: Do not leave turf contents in beforeShuttleMove or dock() will runtime
/atom/movable/proc/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
return move_mode
// Called on atoms to move the atom to the new location
/atom/movable/proc/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
if(newT == oldT) // In case of in place shuttle rotation shenanigans.
return
if(loc != oldT) // This is for multi tile objects
return
loc = newT
return TRUE
// Called on atoms after everything has been moved
/atom/movable/proc/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
var/turf/newT = get_turf(src)
if (newT.z != oldT.z)
onTransitZ(oldT.z, newT.z)
if(light)
update_light()
if(rotation)
shuttleRotate(rotation)
update_parallax_contents()
return TRUE
/atom/movable/proc/lateShuttleMove(turf/oldT, list/movement_force, move_dir)
if(!movement_force || anchored)
return
var/throw_force = movement_force["THROW"]
if(!throw_force)
return
var/turf/target = get_edge_target_turf(src, move_dir)
var/range = throw_force * 10
range = CEILING(rand(range-(range*0.1), range+(range*0.1)), 10)/10
var/speed = range/5
safe_throw_at(target, range, speed, force = MOVE_FORCE_EXTREMELY_STRONG)
/////////////////////////////////////////////////////////////////////////////////////
// Called on areas before anything has been moved
// returns the new move_mode (based on the old)
/area/proc/beforeShuttleMove(list/shuttle_areas)
if(!shuttle_areas[src])
return NONE
return MOVE_AREA
// 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 TRUE
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
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
// Called on areas after everything has been moved
/area/proc/afterShuttleMove(new_parallax_dir)
parallax_movedir = new_parallax_dir
return TRUE
/area/proc/lateShuttleMove()
return
/************************************Turf move procs************************************/
/************************************Area move procs************************************/
/************************************Machinery move procs************************************/
/obj/machinery/door/airlock/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
for(var/obj/machinery/door/airlock/A in range(1, src)) // includes src
A.shuttledocked = FALSE
A.air_tight = TRUE
INVOKE_ASYNC(A, /obj/machinery/door/.proc/close)
/obj/machinery/door/airlock/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
var/current_area = get_area(src)
for(var/obj/machinery/door/airlock/A in orange(1, src)) // does not include src
if(get_area(A) != current_area) // does not include double-wide airlocks unless actually docked
// Cycle linking is only disabled if we are actually adjacent to another airlock
shuttledocked = TRUE
A.shuttledocked = TRUE
/obj/machinery/camera/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
if(. & MOVE_AREA)
. |= MOVE_CONTENTS
GLOB.cameranet.removeCamera(src)
/obj/machinery/camera/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
GLOB.cameranet.addCamera(src)
/obj/machinery/mech_bay_recharge_port/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir)
. = ..()
recharging_turf = get_step(loc, dir)
/obj/machinery/atmospherics/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
if(pipe_vision_img)
pipe_vision_img.loc = loc
/obj/machinery/computer/auxillary_base/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
if(is_mining_level(z)) //Avoids double logging and landing on other Z-levels due to badminnery
SSblackbox.record_feedback("associative", "colonies_dropped", 1, list("x" = x, "y" = y, "z" = z))
/obj/machinery/gravity_generator/main/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
on = FALSE
update_list()
/obj/machinery/gravity_generator/main/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
if(charge_count != 0 && charging_state != POWER_UP)
on = TRUE
update_list()
/obj/machinery/atmospherics/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
var/missing_nodes = FALSE
for(var/i in 1 to device_type)
if(nodes[i])
var/obj/machinery/atmospherics/node = 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(!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(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
var/turf/T = loc
hide(T.intact)
/obj/machinery/navbeacon/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
GLOB.navbeacons["[z]"] -= src
GLOB.deliverybeacons -= src
/obj/machinery/navbeacon/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
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(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
var/turf/T = src.loc
if(level==1)
hide(T.intact)
/************************************Item move procs************************************/
/obj/item/storage/pod/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
// If the pod was launched, the storage will always open. The CentCom check
// ignores the movement of the shuttle from the staging area on CentCom to
// the station as it is loaded in.
if (oldT && !is_centcom_level(oldT.z))
unlocked = TRUE
/************************************Mob move procs************************************/
/mob/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
if(!move_on_shuttle)
return
. = ..()
/mob/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
if(!move_on_shuttle)
return
. = ..()
if(client && movement_force)
var/shake_force = max(movement_force["THROW"], movement_force["KNOCKDOWN"])
if(buckled)
shake_force *= 0.25
shake_camera(src, shake_force, 1)
/mob/living/lateShuttleMove(turf/oldT, list/movement_force, move_dir)
if(buckled)
return
. = ..()
var/knockdown = movement_force["KNOCKDOWN"]
if(knockdown)
Paralyze(knockdown)
/mob/living/simple_animal/hostile/megafauna/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
. = ..()
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(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
if(. & MOVE_AREA)
. |= MOVE_CONTENTS
/obj/structure/lattice/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
if(. & MOVE_AREA)
. |= MOVE_CONTENTS
/obj/structure/disposalpipe/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
update()
/obj/structure/cable/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
cut_cable_from_powernet(FALSE)
/obj/structure/cable/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
var/turf/T = loc
if(level==1)
hide(T.intact)
connect_wire(TRUE)
propogate_if_no_network()
/obj/structure/shuttle/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
if(. & MOVE_AREA)
. |= MOVE_CONTENTS
/obj/structure/ladder/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
if (!(resistance_flags & INDESTRUCTIBLE))
disconnect()
/obj/structure/ladder/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
if (!(resistance_flags & INDESTRUCTIBLE))
LateInitialize()
/obj/structure/ladder/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
if (resistance_flags & INDESTRUCTIBLE)
// simply don't be moved
return FALSE
return ..()
/************************************Misc move procs************************************/
/atom/movable/lighting_object/onShuttleMove()
return FALSE
/obj/docking_port/mobile/beforeShuttleMove(turf/newT, rotation, move_mode, obj/docking_port/mobile/moving_dock)
. = ..()
if(moving_dock == src)
. |= MOVE_CONTENTS
/obj/docking_port/stationary/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
if(!moving_dock.can_move_docking_ports || old_dock == src)
return FALSE
. = ..()
/obj/docking_port/stationary/public_mining_dock/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
id = "mining_public" //It will not move with the base, but will become enabled as a docking point.
/obj/effect/abstract/proximity_checker/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
//timer so it only happens once
addtimer(CALLBACK(monitor, /datum/proximity_monitor/proc/SetRange, monitor.current_range, TRUE), 0, TIMER_UNIQUE)