From a9f07518a737e3ece4e8d40c15aa0adf5196a742 Mon Sep 17 00:00:00 2001 From: Emmett Gaines Date: Tue, 31 Oct 2017 21:23:17 -0400 Subject: [PATCH] Shuttle rotation refactor and significant performance upgrade --- code/__DEFINES/components.dm | 1 + code/__DEFINES/shuttles.dm | 7 +- code/datums/components/turf_decal.dm | 51 ++++++++++ code/game/objects/effects/decals/decal.dm | 16 ++- code/game/turfs/turf.dm | 2 +- .../environmental/LINDA_system.dm | 2 +- code/modules/shuttle/on_move.dm | 98 +++++++++---------- code/modules/shuttle/shuttle.dm | 98 +++++++++++-------- code/modules/shuttle/shuttle_rotate.dm | 60 +++++++----- tgstation.dme | 1 + 10 files changed, 208 insertions(+), 128 deletions(-) create mode 100644 code/datums/components/turf_decal.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index ddfa9942e6..5b3fe2daf0 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -38,6 +38,7 @@ #define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode) #define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size) #define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color) +#define COMSIG_ATOM_ROTATE "atom_rotate" //from base of atom/shuttleRotate(): (rotation, params) #define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params) #define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob) diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index a473f46d2c..26b166fd8c 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -65,4 +65,9 @@ //Docking turf movements #define MOVE_TURF 1 #define MOVE_AREA 2 -#define MOVE_CONTENTS 4 \ No newline at end of file +#define MOVE_CONTENTS 4 + +//Rotation params +#define ROTATE_DIR 1 +#define ROTATE_SMOOTH 2 +#define ROTATE_OFFSET 4 \ No newline at end of file diff --git a/code/datums/components/turf_decal.dm b/code/datums/components/turf_decal.dm new file mode 100644 index 0000000000..0cd4cb969e --- /dev/null +++ b/code/datums/components/turf_decal.dm @@ -0,0 +1,51 @@ +/datum/component/turf_decal + var/dir + var/icon + var/icon_state + var/layer + var/group + +/datum/component/turf_decal/Initialize(_dir, _icon, _icon_state, _layer=TURF_DECAL_LAYER, _group=TURF_DECAL_PAINT) + if(!isturf(parent) || !_icon || !_icon_state) + WARNING("A turf decal was applied incorrectly to [parent]: icon:[_icon ? _icon : "none"] icon_state:[_icon_state ? _icon_state : "none"]") + return COMPONENT_INCOMPATIBLE + + dir = _dir + icon = _icon + icon_state = _icon_state + layer = _layer + group = _group + apply_decal() + + RegisterSignal(COMSIG_ATOM_ROTATE, .proc/rotate_react) + RegisterSignal(COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react) + +/datum/component/turf_decal/Destroy() + remove_decal() + return ..() + +/datum/component/turf_decal/OnTransfer(turf/newT) + remove_decal() + remove_decal(newT) + apply_decal(newT) + +/datum/component/turf_decal/proc/get_decal() + return image(icon, null, icon_state, layer, dir) + +/datum/component/turf_decal/proc/apply_decal(turf/overT) + var/turf/master = overT || parent + master.add_decal(get_decal(), group) + +/datum/component/turf_decal/proc/remove_decal(turf/overT) + var/turf/master = overT || parent + master.remove_decal(group) + +/datum/component/turf_decal/proc/rotate_react(rotation, params) + if(params & ROTATE_DIR) + dir = angle2dir(rotation+dir2angle(dir)) + remove_decal() + apply_decal() + +/datum/component/turf_decal/proc/clean_react(strength) + if(strength >= CLEAN_IMPRESSIVE) + qdel(src) \ No newline at end of file diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm index 520e4e10b7..3ded6ea8fc 100644 --- a/code/game/objects/effects/decals/decal.dm +++ b/code/game/objects/effects/decals/decal.dm @@ -15,24 +15,22 @@ if(T == loc && (isspaceturf(T) || isclosedturf(T) || islava(T) || istype(T, /turf/open/water) || ischasm(T))) qdel(src) +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /obj/effect/turf_decal - var/group = TURF_DECAL_PAINT icon = 'icons/turf/decals.dmi' icon_state = "warningline" - layer = TURF_DECAL_LAYER - anchored = TRUE - -//in case we need some special decals -/obj/effect/turf_decal/proc/get_decal() - return image(icon='icons/turf/decals.dmi',icon_state=icon_state,dir=dir,layer=TURF_LAYER) /obj/effect/turf_decal/Initialize() ..() + return INITIALIZE_HINT_QDEL + +/obj/effect/turf_decal/ComponentInitialize() + . = ..() var/turf/T = loc if(!istype(T)) //you know this will happen somehow CRASH("Turf decal initialized in an object/nullspace") - T.add_decal(get_decal(),group) - return INITIALIZE_HINT_QDEL + T.AddComponent(/datum/component/turf_decal, dir, icon, icon_state) /obj/effect/turf_decal/stripes/line icon_state = "warningline" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 40c026a7cb..127cabb345 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -446,7 +446,7 @@ var/thing = allowed_contents[i] qdel(thing, force=TRUE) - var/turf/newT = ChangeTurf(turf_type, baseturf_type, FALSE, FALSE, forceop = forceop) + var/turf/newT = ChangeTurf(turf_type, baseturf_type, FALSE, FALSE, forceop) SSair.remove_from_active(newT) newT.CalculateAdjacentTurfs() diff --git a/code/modules/atmospherics/environmental/LINDA_system.dm b/code/modules/atmospherics/environmental/LINDA_system.dm index a16e58056b..268528355e 100644 --- a/code/modules/atmospherics/environmental/LINDA_system.dm +++ b/code/modules/atmospherics/environmental/LINDA_system.dm @@ -43,7 +43,7 @@ var/turf/T = get_step(src, direction) if(!T) continue - if(CANATMOSPASS(T, src)) + if( !(blocks_air || T.blocks_air) && CANATMOSPASS(T, src) ) LAZYINITLIST(atmos_adjacent_turfs) LAZYINITLIST(T.atmos_adjacent_turfs) atmos_adjacent_turfs[T] = TRUE diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 70fa37d207..d68777c84a 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -44,40 +44,46 @@ All ShuttleMove procs go here return move_mode // 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) +/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 var/destination_turf_type = newT.type - copyTurf(newT) + newT = copyTurf(newT) newT.baseturf = destination_turf_type - + //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) - //Source turf changes - ChangeTurf(turf_type, baseturf_type, FALSE, TRUE) - - if(rotation) - newT.shuttleRotate(rotation) //see shuttle_rotate.dm - return TRUE // Called on the new turf after everything has been moved -/turf/proc/afterShuttleMove(turf/oldT) +/turf/proc/afterShuttleMove(turf/oldT, turf_type, baseturf_type, rotation) + //Dealing with the turf we left behind + oldT.TransferComponents(src) + oldT.ChangeTurf(turf_type, baseturf_type, FALSE, TRUE) + + // Rotate and let the air move again + if(rotation) + shuttleRotate(rotation) //see shuttle_rotate.dm + return 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) return move_mode // 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, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) +/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 @@ -85,18 +91,18 @@ All ShuttleMove procs go here if(loc != oldT) return - if(rotation) - shuttleRotate(rotation) //see shuttle_rotate.dm loc = newT return TRUE // Called on atoms after everything has been moved -/atom/movable/proc/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/atom/movable/proc/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) if(light) update_light() + if(rotation) + shuttleRotate(rotation) update_parallax_contents() - + return TRUE ///////////////////////////////////////////////////////////////////////////////////// @@ -127,22 +133,12 @@ All ShuttleMove procs go here return TRUE // Called on areas after everything has been moved -/area/proc/afterShuttleMove() +/area/proc/afterShuttleMove(new_parallax_dir) + parallax_movedir = new_parallax_dir return TRUE /************************************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) - /************************************Area move procs************************************/ /************************************Machinery move procs************************************/ @@ -155,7 +151,7 @@ All ShuttleMove procs go here A.air_tight = TRUE INVOKE_ASYNC(A, /obj/machinery/door/.proc/close) -/obj/machinery/door/airlock/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/door/airlock/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() shuttledocked = 1 for(var/obj/machinery/door/airlock/A in range(1, src)) @@ -167,11 +163,11 @@ All ShuttleMove procs go here . |= MOVE_CONTENTS GLOB.cameranet.removeCamera(src) -/obj/machinery/camera/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/camera/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() GLOB.cameranet.addCamera(src) -/obj/machinery/telecomms/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/telecomms/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() listening_level = z // Update listening Z, just in case you have telecomm relay on a shuttle @@ -179,12 +175,12 @@ All ShuttleMove procs go here . = ..() recharging_turf = get_step(loc, dir) -/obj/machinery/atmospherics/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/atmospherics/afterShuttleMove(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(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/computer/auxillary_base/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() 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! @@ -194,7 +190,7 @@ All ShuttleMove procs go here on = FALSE update_list() -/obj/machinery/gravity_generator/main/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/gravity_generator/main/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() if(charge_count != 0 && charging_state != POWER_UP) on = TRUE @@ -205,7 +201,7 @@ All ShuttleMove procs go here if(. & MOVE_AREA) . |= MOVE_CONTENTS -/obj/machinery/atmospherics/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/atmospherics/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/missing_nodes = FALSE for(DEVICE_TYPE_LOOP) @@ -234,7 +230,7 @@ All ShuttleMove procs go here // atmosinit() calls update_icon(), so we don't need to call it update_icon() -/obj/machinery/atmospherics/pipe/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/atmospherics/pipe/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/turf/T = loc hide(T.intact) @@ -244,7 +240,7 @@ All ShuttleMove procs go here GLOB.navbeacons["[z]"] -= src GLOB.deliverybeacons -= src -/obj/machinery/navbeacon/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/navbeacon/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/turf/T = loc hide(T.intact) @@ -256,7 +252,7 @@ All ShuttleMove procs go here GLOB.deliverybeacons += src GLOB.deliverybeacontags += location -/obj/machinery/power/terminal/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/machinery/power/terminal/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/turf/T = src.loc if(level==1) @@ -264,19 +260,19 @@ All ShuttleMove procs go here /************************************Item move procs************************************/ -/obj/item/storage/pod/afterShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock) +/obj/item/storage/pod/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() unlocked = TRUE // If the pod was launched, the storage will always open. /************************************Mob move procs************************************/ -/mob/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) +/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(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/mob/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() if(client && movement_force) var/shake_force = max(movement_force["THROW"], movement_force["KNOCKDOWN"]) @@ -284,7 +280,7 @@ All ShuttleMove procs go here shake_force *= 0.25 shake_camera(src, shake_force, 1) -/mob/living/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/mob/living/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() if(movement_force && !buckled) if(movement_force["THROW"]) @@ -296,7 +292,7 @@ All ShuttleMove procs go here if(movement_force["KNOCKDOWN"]) Knockdown(movement_force["KNOCKDOWN"]) -/mob/living/simple_animal/hostile/megafauna/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) +/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)]") @@ -312,11 +308,11 @@ All ShuttleMove procs go here if(. & MOVE_AREA) . |= MOVE_CONTENTS -/obj/structure/disposalpipe/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/structure/disposalpipe/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() update() -/obj/structure/cable/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) +/obj/structure/cable/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/turf/T = loc if(level==1) @@ -330,20 +326,20 @@ All ShuttleMove procs go here /************************************Misc move procs************************************/ -/atom/movable/lighting_object/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) +/atom/movable/lighting_object/onShuttleMove() return FALSE -/atom/movable/light/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) +/atom/movable/light/onShuttleMove() return FALSE -/obj/docking_port/stationary/onShuttleMove(turf/newT, turf/oldT, rotation, 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)) +/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, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) +/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, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) +/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) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 0f5567fd90..36039353ec 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -513,9 +513,17 @@ return DOCKING_IMMOBILIZED var/obj/docking_port/stationary/old_dock = get_docked() - var/underlying_turf_type = /turf/open/space //The turf that gets placed under where the shuttle moved from - var/underlying_baseturf_type = /turf/open/space //The baseturf that the gets assigned to the turf_type above - var/underlying_area_type = /area/space //The area that gets placed under where the shuttle moved from + + // The turf that gets placed under where the shuttle moved from + var/underlying_turf_type = /turf/open/space + + // The baseturf that the gets assigned to the turf_type above + var/underlying_baseturf_type = /turf/open/space + + // The area that gets placed under where the shuttle moved from + var/underlying_area_type = /area/space + + // The baseturf cache is a typecache of what counts as a baseturf to be left behind var/list/baseturf_cache if(old_dock) //Dock overwrites if(old_dock.turf_type) @@ -527,7 +535,6 @@ if(old_dock.baseturf_cache) baseturf_cache = old_dock.baseturf_cache if(!baseturf_cache) - //Don't want to call this needlessly baseturf_cache = typecacheof(underlying_baseturf_type) /************************************************************************************************************** @@ -540,6 +547,8 @@ var/list/new_turfs = return_ordered_turfs(new_dock.x, new_dock.y, new_dock.z, new_dock.dir) /**************************************************************************************************************/ + // The underlying old area is the area assumed to be under the shuttle's starting location + // If it no longer/has never existed it will be created var/area/underlying_old_area = locate(underlying_area_type) in GLOB.sortedAreas if(!underlying_old_area) underlying_old_area = new underlying_area_type(null) @@ -562,11 +571,11 @@ CHECK_TICK /****************************************All beforeShuttleMove procs*****************************************/ - var/index = 0 - for(var/place in old_turfs) - index++ - var/turf/oldT = place - var/turf/newT = new_turfs[index] + + for(var/i in 1 to old_turfs.len) + CHECK_TICK + var/turf/oldT = old_turfs[i] + var/turf/newT = new_turfs[i] if(!newT) return DOCKING_NULL_DESTINATION if(!oldT) @@ -575,8 +584,9 @@ var/area/old_area = oldT.loc var/move_mode = old_area.beforeShuttleMove(shuttle_areas) //areas - for(var/i in 1 to oldT.contents.len) - var/atom/movable/moving_atom = oldT.contents[i] + var/list/old_contents = oldT.contents + for(var/k in 1 to old_contents.len) + var/atom/movable/moving_atom = old_contents[k] if(moving_atom.loc != oldT) //fix for multi-tile objects continue move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode) //atoms @@ -587,60 +597,70 @@ if(move_mode & MOVE_AREA) areas_to_move[old_area] = TRUE - old_turfs[place] = move_mode - CHECK_TICK + old_turfs[oldT] = move_mode /*******************************************All onShuttleMove procs******************************************/ - index = 0 - for(var/place in old_turfs) - index++ - var/turf/oldT = place - var/turf/newT = new_turfs[index] - var/move_mode = old_turfs[place] + for(var/i in 1 to old_turfs.len) + var/turf/oldT = old_turfs[i] + var/turf/newT = new_turfs[i] + var/move_mode = old_turfs[oldT] if(move_mode & MOVE_CONTENTS) - for(var/thing in oldT) - var/atom/movable/moving_atom = thing + for(var/k in oldT) + var/atom/movable/moving_atom = k if(moving_atom.loc != oldT) //fix for multi-tile objects continue - moving_atom.onShuttleMove(newT, oldT, rotation, movement_force, movement_direction, old_dock, src)//atoms + moving_atom.onShuttleMove(newT, oldT, movement_force, movement_direction, old_dock, src) //atoms moved_atoms += moving_atom + if(move_mode & MOVE_TURF) - oldT.onShuttleMove(newT, underlying_turf_type, underlying_baseturf_type, rotation, movement_force, movement_direction)//turfs + oldT.onShuttleMove(newT, movement_force, movement_direction) //turfs + if(move_mode & MOVE_AREA) var/area/shuttle_area = oldT.loc shuttle_area.onShuttleMove(oldT, newT, underlying_old_area) //areas /******************************************All afterShuttleMove procs****************************************/ - index = 0 - for(var/thing in old_turfs) - index++ - var/turf/oldT = thing - var/turf/newT = new_turfs[index] - newT.afterShuttleMove(oldT) //turfs + for(var/i in 1 to old_turfs.len) CHECK_TICK + if(!(old_turfs[old_turfs[i]] & MOVE_TURF)) + continue + var/turf/oldT = old_turfs[i] + var/turf/newT = new_turfs[i] + newT.afterShuttleMove(oldT, underlying_turf_type, underlying_baseturf_type, rotation) //turfs 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 CHECK_TICK + var/atom/movable/moved_object = moved_atoms[i] + moved_object.afterShuttleMove(movement_force, dir, preferred_direction, movement_direction, rotation)//atoms + + for(var/i in 1 to old_turfs.len) + CHECK_TICK + // Objects can block air so either turf or content changes means an air update is needed + if(!(old_turfs[old_turfs[i]] & MOVE_CONTENTS | MOVE_TURF)) + continue + var/turf/oldT = old_turfs[i] + var/turf/newT = new_turfs[i] + oldT.blocks_air = initial(oldT.blocks_air) + oldT.air_update_turf(TRUE) + newT.blocks_air = initial(newT.blocks_air) + newT.air_update_turf(TRUE) underlying_old_area.afterShuttleMove() - for(var/thing in areas_to_move) - var/area/internal_area = thing - internal_area.afterShuttleMove() //areas - CHECK_TICK - // Parallax handling var/new_parallax_dir = FALSE if(istype(new_dock, /obj/docking_port/stationary/transit)) new_parallax_dir = preferred_direction - for(var/i in shuttle_areas) - var/area/place = i - place.parallax_movedir = new_parallax_dir + for(var/i in 1 to areas_to_move.len) CHECK_TICK +<<<<<<< HEAD +======= + var/area/internal_area = areas_to_move[i] + internal_area.afterShuttleMove(new_parallax_dir) //areas + +>>>>>>> 4d420b8... Shuttle rotation refactor and significant performance upgrade (#31942) check_poddoors() new_dock.last_dock_time = world.time setDir(new_dock.dir) diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm index d7e5f5eee7..d322f2cd32 100644 --- a/code/modules/shuttle/shuttle_rotate.dm +++ b/code/modules/shuttle/shuttle_rotate.dm @@ -6,50 +6,55 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate /************************************Base proc************************************/ -/atom/proc/shuttleRotate(rotation) - //rotate our direction - setDir(angle2dir(rotation+dir2angle(dir))) +/atom/proc/shuttleRotate(rotation, params=ROTATE_DIR|ROTATE_SMOOTH|ROTATE_OFFSET) + if(params & ROTATE_DIR) + //rotate our direction + setDir(angle2dir(rotation+dir2angle(dir))) //resmooth if need be. - if(smooth) + if(smooth && (params & ROTATE_SMOOTH)) queue_smooth(src) //rotate the pixel offsets too. - if (pixel_x || pixel_y) - if (rotation < 0) + if((pixel_x || pixel_y) && (params & ROTATE_OFFSET)) + if(rotation < 0) rotation += 360 - for (var/turntimes=rotation/90;turntimes>0;turntimes--) + for(var/turntimes=rotation/90;turntimes>0;turntimes--) var/oldPX = pixel_x var/oldPY = pixel_y pixel_x = oldPY pixel_y = (oldPX*(-1)) + SendSignal(COMSIG_ATOM_ROTATE, rotation, params) + /************************************Turf rotate procs************************************/ -/turf/closed/mineral/shuttleRotate(rotation) - setDir(angle2dir(rotation+dir2angle(dir))) - queue_smooth(src) +/turf/closed/mineral/shuttleRotate(rotation, params) + params &= ~ROTATE_OFFSET + return ..() /************************************Mob rotate procs************************************/ //override to avoid rotating pixel_xy on mobs -/mob/shuttleRotate(rotation) +/mob/shuttleRotate(rotation, params) + params = NONE + . = ..() if(!buckled) setDir(angle2dir(rotation+dir2angle(dir))) -/mob/dead/observer/shuttleRotate(rotation) +/mob/dead/observer/shuttleRotate(rotation, params) . = ..() update_icon() /************************************Structure rotate procs************************************/ -/obj/structure/door_assembly/door_assembly_pod/shuttleRotate(rotation) +/obj/structure/door_assembly/door_assembly_pod/shuttleRotate(rotation, params) . = ..() expected_dir = angle2dir(rotation+dir2angle(dir)) -/obj/structure/cable/shuttleRotate(rotation) - //..() is not called because wires are not supposed to have a non-default direction - //Rotate connections +/obj/structure/cable/shuttleRotate(rotation, params) + params &= ~ROTATE_DIR + . = ..() if(d1) d1 = angle2dir(rotation+dir2angle(d1)) if(d2) @@ -63,7 +68,7 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate update_icon() //Fixes dpdir on shuttle rotation -/obj/structure/disposalpipe/shuttleRotate(rotation) +/obj/structure/disposalpipe/shuttleRotate(rotation, params) . = ..() var/new_dpdir = 0 for(var/D in GLOB.cardinals) @@ -71,16 +76,17 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate new_dpdir = new_dpdir | angle2dir(rotation+dir2angle(D)) dpdir = new_dpdir -/obj/structure/table/wood/bar/shuttleRotate(rotation) +/obj/structure/table/wood/bar/shuttleRotate(rotation, params) . = ..() boot_dir = angle2dir(rotation + dir2angle(boot_dir)) -/obj/structure/alien/weeds/shuttleRotate(rotation) - return +/obj/structure/alien/weeds/shuttleRotate(rotation, params) + params &= ~ROTATE_OFFSET + return ..() /************************************Machine rotate procs************************************/ -/obj/machinery/atmospherics/shuttleRotate(rotation) +/obj/machinery/atmospherics/shuttleRotate(rotation, params) var/list/real_node_connect = getNodeConnects() for(DEVICE_TYPE_LOOP) real_node_connect[I] = angle2dir(rotation+dir2angle(real_node_connect[I])) @@ -95,13 +101,15 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate nodes[new_pos] = nodes_copy[I] //prevents shuttles attempting to rotate this since it messes up sprites -/obj/machinery/gateway/shuttleRotate() - return +/obj/machinery/gateway/shuttleRotate(rotation, params) + params = NONE + return ..() -/obj/machinery/door/airlock/survival_pod/shuttleRotate(rotation) +/obj/machinery/door/airlock/survival_pod/shuttleRotate(rotation, params) expected_dir = angle2dir(rotation+dir2angle(dir)) return ..() //prevents shuttles attempting to rotate this since it messes up sprites -/obj/machinery/gravity_generator/shuttleRotate() - return \ No newline at end of file +/obj/machinery/gravity_generator/shuttleRotate(rotation, params) + params = NONE + return ..() \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 1f7eec78df..b2451e170e 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -326,6 +326,7 @@ #include "code\datums\components\spooky.dm" #include "code\datums\components\squeek.dm" #include "code\datums\components\thermite.dm" +#include "code\datums\components\turf_decal.dm" #include "code\datums\diseases\_disease.dm" #include "code\datums\diseases\_MobProcs.dm" #include "code\datums\diseases\anxiety.dm"