diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index f447a13be77..1147d3d0209 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -334,6 +334,8 @@ #define COMSIG_TURF_MULTIZ_DEL "turf_multiz_del" ///from base of turf/multiz_turf_new: (turf/source, direction) #define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" +///from base of turf/proc/onShuttleMove(): (turf/new_turf) +#define COMSIG_TURF_ON_SHUTTLE_MOVE "turf_on_shuttle_move" // /atom/movable signals diff --git a/code/datums/elements/decal.dm b/code/datums/elements/decal.dm index 5cf4b8a5e9e..dbd0228b2a2 100644 --- a/code/datums/elements/decal.dm +++ b/code/datums/elements/decal.dm @@ -3,14 +3,69 @@ id_arg_index = 2 var/cleanable var/description + /// If true this was initialized with no set direction - will follow the parent dir. + var/directional var/mutable_appearance/pic -/datum/element/decal/Attach(atom/target, _icon, _icon_state, _dir, _cleanable=FALSE, _color, _layer=TURF_LAYER, _description, _alpha=255) +/// Remove old decals and apply new decals after rotation as necessary +/datum/controller/subsystem/processing/dcs/proc/rotate_decals(datum/source, old_dir, new_dir) + SIGNAL_HANDLER + + if(old_dir == new_dir) + return + var/list/resulting_decals_params = list() // param lists + var/list/old_decals = list() //instances + + if(!source.comp_lookup || !source.comp_lookup[COMSIG_ATOM_UPDATE_OVERLAYS]) + //should probably also unregister itself + return + + if(length(source.comp_lookup[COMSIG_ATOM_UPDATE_OVERLAYS])) + for(var/datum/element/decal/decal in source.comp_lookup[COMSIG_ATOM_UPDATE_OVERLAYS]) + old_decals += decal + resulting_decals_params += list(decal.get_rotated_parameters(old_dir,new_dir)) + else + var/datum/element/decal/decal = source.comp_lookup[COMSIG_ATOM_UPDATE_OVERLAYS] + if(!istype(decal)) + return + old_decals += decal + resulting_decals_params += list(decal.get_rotated_parameters(old_dir,new_dir)) + + //Instead we could generate ids and only remove duplicates to save on churn on four-corners symmetry ? + for(var/datum/element/decal/decal in old_decals) + decal.Detach(source) + + for(var/result in resulting_decals_params) + source.AddElement(/datum/element/decal, result["icon"], result["icon_state"], result["dir"], result["cleanable"], result["color"], result["layer"], result["desc"], result["alpha"]) + + +/datum/element/decal/proc/get_rotated_parameters(old_dir,new_dir) + var/rotation = 0 + if(directional) //Even when the dirs are the same rotation is coming out as not 0 for some reason + rotation = SIMPLIFY_DEGREES(dir2angle(new_dir)-dir2angle(old_dir)) + new_dir = turn(pic.dir,-rotation) + return list( + "icon" = pic.icon, + "icon_state" = pic.icon_state, + "dir" = new_dir, + "cleanable" = cleanable, + "color" = pic.color, + "layer" = pic.layer, + "desc" = description, + "alpha" = pic.alpha + ) + + + +/datum/element/decal/Attach(atom/target, _icon, _icon_state, _dir, _cleanable=FALSE, _color, _layer=TURF_LAYER, _description, _alpha=255, mutable_appearance/_pic) . = ..() if(!isatom(target) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha, target)) return ELEMENT_INCOMPATIBLE + if(_pic) + pic = _pic description = _description cleanable = _cleanable + directional = _dir RegisterSignal(target,COMSIG_ATOM_UPDATE_OVERLAYS,.proc/apply_overlay, TRUE) if(target.flags_1 & INITIALIZED_1) @@ -20,12 +75,14 @@ if(isitem(target)) INVOKE_ASYNC(target, /obj/item/.proc/update_slot_icon, TRUE) if(_dir) - RegisterSignal(target, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react,TRUE) + SSdcs.RegisterSignal(target,COMSIG_ATOM_DIR_CHANGE, /datum/controller/subsystem/processing/dcs/proc/rotate_decals, TRUE) if(_cleanable) RegisterSignal(target, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react,TRUE) if(_description) RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/examine,TRUE) + RegisterSignal(target, COMSIG_TURF_ON_SHUTTLE_MOVE, .proc/shuttle_move_react,TRUE) + /datum/element/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha, source) if(!_icon || !_icon_state) return FALSE @@ -36,7 +93,7 @@ return TRUE /datum/element/decal/Detach(atom/source, force) - UnregisterSignal(source, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS)) + UnregisterSignal(source, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_TURF_ON_SHUTTLE_MOVE)) source.update_appearance() if(isitem(source)) INVOKE_ASYNC(source, /obj/item/.proc/update_slot_icon) @@ -55,15 +112,6 @@ overlay_list += pic - -/datum/element/decal/proc/rotate_react(datum/source, old_dir, new_dir) - SIGNAL_HANDLER - - if(old_dir == new_dir) - return - Detach(source) - source.AddElement(/datum/element/decal, pic.icon, pic.icon_state, new_dir, cleanable, pic.color, pic.layer, description, pic.alpha) - /datum/element/decal/proc/clean_react(datum/source, clean_types) SIGNAL_HANDLER @@ -76,3 +124,11 @@ SIGNAL_HANDLER examine_list += description + +/datum/element/decal/proc/shuttle_move_react(datum/source, turf/new_turf) + SIGNAL_HANDLER + + if(new_turf == source) + return + Detach(source) + new_turf.AddElement(/datum/element/decal, pic.icon, pic.icon_state, directional, cleanable, pic.color, pic.layer, description, pic.alpha) diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 65f97178afd..bba1a24321a 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -56,7 +56,6 @@ All ShuttleMove procs go here 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, FALSE) blocks_air = TRUE @@ -64,6 +63,7 @@ All ShuttleMove procs go here if(isopenturf(newT)) var/turf/open/new_open = newT new_open.copy_air_with_tile(src) + SEND_SIGNAL(src, COMSIG_TURF_ON_SHUTTLE_MOVE, newT) return TRUE