General maintenance for wall mounts (#93534)

## About The Pull Request
- Fixes #93392
- Replaces all custom callbacks with call to `deconstruct()`. The
callbacks weren't necessary as it did the same thing as `deconstruct()`
but in an round about way
- Removed duplicate `Initialize()` procs and the params `building` &
`ndir` from all wall mounts. Makes everything cleaner

## Changelog
🆑
fix: wall mounts placed by player now falls off when the wall they are
mounted on is destroyed
code: cleaned up wall mount code
/🆑
This commit is contained in:
SyncIt21
2025-10-23 20:56:19 +05:30
committed by GitHub
parent d2a9f9b191
commit 9740c687de
39 changed files with 173 additions and 223 deletions

View File

@@ -2,40 +2,26 @@
/datum/component/wall_mounted
dupe_mode = COMPONENT_DUPE_ALLOWED
/// The wall our object is currently linked to.
var/turf/hanging_wall_turf
/// Callback to the parent's proc to call on the linked object when the wall disappear's or changes.
var/datum/callback/on_drop
var/turf/closed/wall/hanging_wall_turf
/datum/component/wall_mounted/Initialize(target_wall, on_drop_callback)
. = ..()
if(!isobj(parent))
return COMPONENT_INCOMPATIBLE
if(!isturf(target_wall))
if(!isobj(parent) || !iswallturf(target_wall))
return COMPONENT_INCOMPATIBLE
hanging_wall_turf = target_wall
on_drop = on_drop_callback
/datum/component/wall_mounted/RegisterWithParent()
ADD_TRAIT(parent, TRAIT_WALLMOUNTED, REF(src))
RegisterSignal(hanging_wall_turf, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
RegisterSignal(hanging_wall_turf, COMSIG_TURF_CHANGE, PROC_REF(on_turf_changing))
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(on_linked_destroyed))
/datum/component/wall_mounted/UnregisterFromParent()
REMOVE_TRAIT(parent, TRAIT_WALLMOUNTED, REF(src))
UnregisterSignal(hanging_wall_turf, list(COMSIG_ATOM_EXAMINE, COMSIG_TURF_CHANGE))
UnregisterSignal(parent, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED))
UnregisterSignal(parent, COMSIG_MOVABLE_MOVED)
hanging_wall_turf = null
/**
* Basic reference handling if the hanging/linked object is destroyed first.
*/
/datum/component/wall_mounted/proc/on_linked_destroyed()
SIGNAL_HANDLER
if(!QDELING(src))
qdel(src)
/**
* When the wall is examined, explains that it's supporting the linked object.
*/
@@ -49,7 +35,8 @@
*/
/datum/component/wall_mounted/proc/on_turf_changing(datum/source, path, new_baseturfs, flags, post_change_callbacks)
SIGNAL_HANDLER
if (ispath(path, /turf/open))
if(ispath(path, /turf/open))
drop_wallmount()
@@ -69,34 +56,21 @@
* Except for intercoms, which are handled by creating a new wallframe intercom, as they're apparently items.
*/
/datum/component/wall_mounted/proc/drop_wallmount()
SIGNAL_HANDLER
PRIVATE_PROC(TRUE)
var/obj/hanging_parent = parent
if(on_drop)
hanging_parent.visible_message(message = span_warning("\The [hanging_parent] falls off the wall!"), vision_distance = 5)
on_drop.Invoke(hanging_parent)
else
hanging_parent.visible_message(message = span_warning("\The [hanging_parent] falls apart!"), vision_distance = 5)
hanging_parent.deconstruct()
hanging_parent.deconstruct(FALSE)
if(!QDELING(src))
qdel(src) //Well, we fell off the wall, so we're done here.
/**
* Checks object direction and then verifies if there's a wall in that direction. Finally, applies a wall_mounted component to the object.
*
* @param directional If TRUE, will use the direction of the object to determine the wall to attach to. If FALSE, will use the object's loc.
* @param custom_drop_callback If set, will use this callback instead of the default deconstruct callback.
*/
/obj/proc/find_and_hang_on_wall(directional = TRUE, custom_drop_callback)
///Checks object direction and then verifies if there's a wall in that direction. Finally, applies a wall_mounted component to the object.
/obj/proc/find_and_hang_on_wall()
if(istype(get_area(src), /area/shuttle))
return FALSE //For now, we're going to keep the component off of shuttles to avoid the turf changing issue. We'll hit that later really;
var/turf/attachable_wall
if(directional)
attachable_wall = get_step(src, dir)
else
attachable_wall = loc ///Pull from the curent object loc
var/turf/attachable_wall = loc //first attempt to locate a wall in our current turf
if(!iswallturf(attachable_wall))
return FALSE//Nothing to latch onto, or not the right thing.
src.AddComponent(/datum/component/wall_mounted, attachable_wall, custom_drop_callback)
attachable_wall = get_step(src, dir) //if no then attempt to locate it in our direction
if(!iswallturf(attachable_wall))
return FALSE //Nothing to latch onto, or not the right thing.
AddComponent(/datum/component/wall_mounted, attachable_wall)
return TRUE

View File

@@ -30,6 +30,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/barsign, 32)
//Roundstart/map specific barsigns "belong" in their area and should be renaming it, signs created from wallmounts will not.
change_area_name = mapload
set_sign(new /datum/barsign/hiddensigns/signoff)
if(mapload)
find_and_hang_on_wall()
/obj/machinery/barsign/proc/set_sign(datum/barsign/sign)

View File

@@ -44,16 +44,12 @@
* INITIALIZATION
*/
/obj/machinery/button/Initialize(mapload, ndir = 0, built = 0)
/obj/machinery/button/Initialize(mapload)
. = ..()
if(built)
setDir(ndir)
if(!mapload)
set_panel_open(TRUE)
update_appearance()
if(!built && !device && device_type)
device = new device_type(src)
check_access(null)
if(length(req_access) || length(req_one_access))
@@ -64,7 +60,8 @@
board.one_access = 1
board.accesses = req_one_access
setup_device()
setup_device(mapload)
if(mapload)
find_and_hang_on_wall()
register_context()
@@ -73,7 +70,9 @@
QDEL_NULL(board)
return ..()
/obj/machinery/button/proc/setup_device()
/obj/machinery/button/proc/setup_device(mapload)
if(mapload && !device && device_type)
device = new device_type(src)
if(id && istype(device, /obj/item/assembly/control))
var/obj/item/assembly/control/control_device = device
control_device.id = id
@@ -401,17 +400,17 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/button/door, 24)
/obj/machinery/button/door/indestructible
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
/obj/machinery/button/door/setup_device()
if(!device)
if(normaldoorcontrol)
var/obj/item/assembly/control/airlock/airlock_device = new(src)
/obj/machinery/button/door/setup_device(mapload)
if(mapload)
device = normaldoorcontrol ? new /obj/item/assembly/control/airlock(src) : new /obj/item/assembly/control(src)
if(istype(device, /obj/item/assembly/control/airlock))
var/obj/item/assembly/control/airlock/airlock_device = device
airlock_device.specialfunctions = specialfunctions
device = airlock_device
else
var/obj/item/assembly/control/control_device = new(src)
else if(istype(device, /obj/item/assembly/control))
var/obj/item/assembly/control/control_device = device
control_device.sync_doors = sync_doors
device = control_device
..()
return ..()
/obj/machinery/button/door/incinerator_vent_ordmix
name = "combustion chamber vent control"
@@ -499,10 +498,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/button/door, 24)
device_type = /obj/item/assembly/control/curtain
var/sync_doors = TRUE
/obj/machinery/button/curtain/setup_device()
/obj/machinery/button/curtain/setup_device(mapload)
. = ..()
var/obj/item/assembly/control/curtain = device
if(istype(curtain))
curtain.sync_doors = sync_doors
return ..()
/obj/machinery/button/crematorium
name = "crematorium igniter"

View File

@@ -103,12 +103,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)
fire = 90
acid = 50
/obj/machinery/camera/Initialize(mapload, ndir, building)
/obj/machinery/camera/Initialize(mapload)
. = ..()
if(building)
setDir(ndir)
for(var/network_name in network)
network -= network_name
network += LOWER_TEXT(network_name)
@@ -130,8 +127,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)
#endif
alarm_manager = new(src)
find_and_hang_on_wall(directional = TRUE, \
custom_drop_callback = CALLBACK(src, PROC_REF(deconstruct), FALSE))
if(mapload)
find_and_hang_on_wall()
/obj/machinery/camera/Destroy(force)
if(can_use())

View File

@@ -70,6 +70,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/security/telescreen/entertai
/obj/machinery/computer/security/telescreen/entertainment/Initialize(mapload)
. = ..()
if(mapload)
find_and_hang_on_wall()
register_context()
RegisterSignal(SSdcs, COMSIG_GLOB_NETWORK_BROADCAST_UPDATED, PROC_REF(on_network_broadcast_updated))

View File

@@ -24,6 +24,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount, 28)
/obj/machinery/defibrillator_mount/loaded/Initialize(mapload) //loaded subtype for mapping use
. = ..()
defib = new/obj/item/defibrillator/loaded(src)
if(mapload)
find_and_hang_on_wall()
/obj/machinery/defibrillator_mount/Destroy()

View File

@@ -80,6 +80,7 @@
/obj/machinery/digital_clock/Initialize(mapload)
. = ..()
if(mapload)
find_and_hang_on_wall()
AddElement(/datum/element/beauty, 200)

View File

@@ -49,10 +49,10 @@
fire = 90
acid = 30
/obj/machinery/firealarm/Initialize(mapload, dir, building)
/obj/machinery/firealarm/Initialize(mapload)
. = ..()
id_tag = assign_random_name()
if(building)
if(!mapload)
buildstage = FIRE_ALARM_BUILD_NO_CIRCUIT
set_panel_open(TRUE)
if(name == initial(name))
@@ -78,10 +78,10 @@
)
register_context()
if(mapload)
find_and_hang_on_wall()
update_appearance()
/obj/machinery/firealarm/Destroy()
if(my_area)
LAZYREMOVE(my_area.firealarms, src)

View File

@@ -24,9 +24,9 @@
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/flasher, 26)
/obj/machinery/flasher/Initialize(mapload, ndir = 0, built = 0)
. = ..() // ..() is EXTREMELY IMPORTANT, never forget to add it
if(!built)
/obj/machinery/flasher/Initialize(mapload)
. = ..()
if(mapload)
bulb = new(src)
find_and_hang_on_wall()

View File

@@ -163,6 +163,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/sparker, 26)
spark_system.set_up(2, 1, src)
spark_system.attach(src)
register_context()
if(mapload)
find_and_hang_on_wall()
/obj/machinery/sparker/Destroy()

View File

@@ -34,7 +34,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light_switch, 26)
area = get_area(src)
if(autoname)
name = "light switch ([area.name])"
find_and_hang_on_wall(custom_drop_callback = CALLBACK(src, PROC_REF(deconstruct), TRUE))
if(mapload)
find_and_hang_on_wall()
register_context()
update_appearance()

View File

@@ -72,11 +72,12 @@
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
/obj/machinery/newscaster/Initialize(mapload, ndir, building)
/obj/machinery/newscaster/Initialize(mapload)
. = ..()
GLOB.allCasters += src
GLOB.allbountyboards += src
update_appearance()
if(mapload)
find_and_hang_on_wall()
/obj/machinery/newscaster/Destroy()

View File

@@ -957,12 +957,13 @@ DEFINE_BITFIELD(turret_flags, list(
/// List of weakrefs to all turrets
var/list/turrets = list()
/obj/machinery/turretid/Initialize(mapload, ndir = 0, built = 0)
/obj/machinery/turretid/Initialize(mapload)
. = ..()
if(built)
if(!mapload)
locked = FALSE
power_change() //Checks power and initial settings
else
find_and_hang_on_wall()
power_change() //Checks power and initial settings
/obj/machinery/turretid/Destroy()
turrets.Cut()

View File

@@ -128,6 +128,7 @@ GLOBAL_LIST_EMPTY(req_console_ckey_departments)
if(dept_key)
LAZYADD(GLOB.reta_consoles_by_origin[dept_key], src)
if(mapload)
find_and_hang_on_wall()
/obj/machinery/requests_console/Destroy()

View File

@@ -51,7 +51,7 @@ GLOBAL_DATUM_INIT(status_font, /datum/font, new /datum/font/tiny_unicode/size_12
pixel_shift = 32
//makes it go on the wall when built
/obj/machinery/status_display/Initialize(mapload, ndir, building)
/obj/machinery/status_display/Initialize(mapload)
. = ..()
update_appearance()
@@ -407,6 +407,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32)
/obj/item/circuit_component/status_display,
))
RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, PROC_REF(on_sec_level_change))
if(mapload)
find_and_hang_on_wall()
/obj/machinery/status_display/evac/Destroy()
@@ -842,7 +843,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/ai, 32)
/// list to pick the first line from
var/list/firstline_to_secondline = list()
/obj/machinery/status_display/random_message/Initialize(mapload, ndir, building)
/obj/machinery/status_display/random_message/Initialize(mapload)
if(firstline_to_secondline?.len)
message1 = pick(firstline_to_secondline)
message2 = firstline_to_secondline[message1]

View File

@@ -69,6 +69,8 @@
update_appearance()
init_payment()
register_context()
if(mapload)
find_and_hang_on_wall()
/obj/machinery/wall_healer/Destroy()
clear_using_mob()

View File

@@ -28,24 +28,27 @@
icon_state = "intercom_prison"
icon_off = "intercom_prison-p"
/obj/item/radio/intercom/prison/Initialize(mapload, ndir, building)
/obj/item/radio/intercom/prison/Initialize(mapload)
. = ..()
wires?.cut(WIRE_TX)
/obj/item/radio/intercom/Initialize(mapload, ndir, building)
/obj/item/radio/intercom/Initialize(mapload)
. = ..()
var/area/current_area = get_area(src)
if(!current_area)
return
RegisterSignal(current_area, COMSIG_AREA_POWER_CHANGE, PROC_REF(AreaPowerCheck))
if(mapload)
find_and_hang_on_wall()
GLOB.intercoms_list += src
/obj/item/radio/intercom/find_and_hang_on_wall()
if(!unscrewed)
find_and_hang_on_wall(directional = TRUE, \
custom_drop_callback = CALLBACK(src, PROC_REF(knock_down)))
return ..()
/obj/item/radio/intercom/Destroy()
. = ..()
GLOB.intercoms_list -= src
return ..()
/obj/item/radio/intercom/examine(mob/user)
. = ..()
@@ -87,7 +90,7 @@
if(tool.use_tool(src, user, 80))
user.visible_message(span_notice("[user] unsecures [src]!"), span_notice("You detach [src] from the wall."))
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
knock_down()
deconstruct(TRUE)
/**
* Override attack_tk_grab instead of attack_tk because we actually want attack_tk's
@@ -187,9 +190,8 @@
/**
* Called by the wall mount component and reused during the tool deconstruction proc.
*/
/obj/item/radio/intercom/proc/knock_down()
/obj/item/radio/intercom/atom_deconstruct(disassembled)
new/obj/item/wallframe/intercom(get_turf(src))
qdel(src)
//Created through the autolathe or through deconstructing intercoms. Can be applied to wall to make a new intercom on it!
/obj/item/wallframe/intercom
@@ -209,7 +211,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/item/radio/intercom, 27)
anonymize = TRUE
freqlock = RADIO_FREQENCY_EMAGGABLE_LOCK
/obj/item/radio/intercom/chapel/Initialize(mapload, ndir, building)
/obj/item/radio/intercom/chapel/Initialize(mapload)
. = ..()
set_frequency(1481)
set_broadcasting(TRUE)

View File

@@ -40,7 +40,7 @@
span_hear("You hear clicking."))
var/floor_to_wall = get_dir(user, on_wall)
var/obj/hanging_object = new result_path(get_turf(user), floor_to_wall, TRUE)
var/obj/hanging_object = new result_path(get_turf(user))
hanging_object.setDir(floor_to_wall)
if(pixel_shift)
switch(floor_to_wall)
@@ -52,6 +52,7 @@
hanging_object.pixel_x = pixel_shift
if(WEST)
hanging_object.pixel_x = -pixel_shift
hanging_object.find_and_hang_on_wall()
after_attach(hanging_object)
qdel(src)

View File

@@ -34,9 +34,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/detectiveboard, 32)
if(istype(item, /obj/item/paper) || istype(item, /obj/item/photo))
item.forceMove(src)
cases[current_case].notices++
find_and_hang_on_wall()
register_context()
find_and_hang_on_wall()
/// Attaching evidences: photo and papers

View File

@@ -12,15 +12,15 @@
MAPPING_DIRECTIONAL_HELPERS(/obj/structure/extinguisher_cabinet, 29)
/obj/structure/extinguisher_cabinet/Initialize(mapload, ndir, building)
/obj/structure/extinguisher_cabinet/Initialize(mapload)
. = ..()
if(building)
if(!mapload)
opened = TRUE
else
stored_extinguisher = new /obj/item/extinguisher(src)
find_and_hang_on_wall()
update_appearance(UPDATE_ICON)
register_context()
find_and_hang_on_wall()
/obj/structure/extinguisher_cabinet/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()

View File

@@ -38,6 +38,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fireaxecabinet, 32)
if(populate_contents)
held_item = new item_path(src)
update_appearance()
if(mapload)
find_and_hang_on_wall()
/obj/structure/fireaxecabinet/Destroy()

View File

@@ -34,10 +34,6 @@
///List of all Races that can be chosen, decided by its Initialize.
var/list/selectable_races = list()
/obj/structure/mirror/Initialize(mapload)
. = ..()
update_choices()
/obj/structure/mirror/Destroy()
mirror_options = null
selectable_races = null
@@ -58,6 +54,10 @@
update_signals = list(COMSIG_ATOM_BREAK), \
check_reflect_signals = list(SIGNAL_ADDTRAIT(TRAIT_NO_MIRROR_REFLECTION), SIGNAL_REMOVETRAIT(TRAIT_NO_MIRROR_REFLECTION)), \
)
if(mapload)
find_and_hang_on_wall()
update_choices()
register_context()
/obj/structure/mirror/proc/can_reflect(atom/movable/target)
///I'm doing it this way too, because the signal is sent before the broken variable is set to TRUE.
@@ -69,11 +69,6 @@
MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28)
/obj/structure/mirror/Initialize(mapload)
. = ..()
find_and_hang_on_wall()
register_context()
/obj/structure/mirror/broken
icon_state = "mirror_broke"

View File

@@ -35,6 +35,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/noticeboard, 32)
paper.forceMove(src)
notices++
update_appearance(UPDATE_ICON)
if(mapload)
find_and_hang_on_wall()
//attaching papers!!

View File

@@ -104,15 +104,16 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/secure_safe, 32)
/obj/structure/secure_safe/Initialize(mapload)
. = ..()
//this will create the storage for us.
AddComponent(/datum/component/lockable_storage, stored_lock_code)
if(!density)
find_and_hang_on_wall()
AddComponent(/datum/component/lockable_storage, , stored_lock_code)
if(mapload)
PopulateContents()
find_and_hang_on_wall()
RegisterSignal(src, COMSIG_LOCKABLE_STORAGE_SET_CODE, PROC_REF(update_lock_code))
/obj/structure/secure_safe/find_and_hang_on_wall()
if(!density)
return ..()
/obj/structure/secure_safe/atom_deconstruct(disassembled)
if(!density) //if we're a wall item, we'll drop a wall frame.
var/obj/item/wallframe/secure_safe/new_safe = new(get_turf(src))

View File

@@ -14,8 +14,6 @@
var/is_editable = FALSE
///sign_change_name is used to make nice looking, alphabetized and categorized names when you use a pen on any sign item or structure which is_editable.
var/sign_change_name
///Callback to the knock down proc for wallmounting behavior.
var/knock_down_callback
/datum/armor/structure_sign
melee = 50
@@ -25,12 +23,8 @@
/obj/structure/sign/Initialize(mapload)
. = ..()
register_context()
knock_down_callback = CALLBACK(src, PROC_REF(knock_down))
find_and_hang_on_wall(custom_drop_callback = knock_down_callback)
/obj/structure/sign/Destroy()
. = ..()
knock_down_callback = null
if(mapload)
find_and_hang_on_wall()
/obj/structure/sign/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
@@ -63,7 +57,7 @@
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
user.visible_message(span_notice("[user] unfastens [src]."), \
span_notice("You unfasten [src]."))
knock_down(user)
deconstruct(TRUE)
return TRUE
/obj/structure/sign/welder_act(mob/living/user, obj/item/I)
@@ -112,16 +106,8 @@
return
return ..()
/**
* This is called when a sign is removed from a wall, either through deconstruction or being knocked down.
* @param mob/living/user The user who removed the sign, if it was knocked down by a mob.
*/
/obj/structure/sign/proc/knock_down(mob/living/user)
var/turf/drop_turf
if(user)
drop_turf = get_turf(user)
else
drop_turf = drop_location()
/obj/structure/sign/atom_deconstruct(disassembled)
var/turf/drop_turf = drop_location()
var/obj/item/sign/unwrenched_sign = new (drop_turf)
if(type != /obj/structure/sign/blank) //If it's still just a basic sign backing, we can (and should) skip some of the below variable transfers.
unwrenched_sign.name = name //Copy over the sign structure variables to the sign item we're creating when we unwrench a sign.
@@ -133,7 +119,6 @@
unwrenched_sign.is_editable = is_editable
unwrenched_sign.update_integrity(get_integrity()) //Transfer how damaged it is.
unwrenched_sign.setDir(dir)
qdel(src) //The sign structure on the wall goes poof and only the sign item from unwrenching remains.
/obj/structure/sign/blank //This subtype is necessary for now because some other things (posters, picture frames, paintings) inherit from the parent type.
icon_state = "backing"
@@ -217,6 +202,9 @@
var/obj/structure/sign/placed_sign = new sign_path(user_turf) //We place the sign on the turf the user is standing, and pixel shift it to the target wall, as below.
//This is to mimic how signs and other wall objects are usually placed by mappers, and so they're only visible from one side of a wall.
var/dir = get_dir(user_turf, target_turf)
if(!(dir in GLOB.cardinals))
balloon_alert(user, "stand in line with wall!")
return
if(dir & NORTH)
placed_sign.pixel_y = 32
else if(dir & SOUTH)
@@ -230,7 +218,7 @@
playsound(target_turf, 'sound/items/deconstruct.ogg', 50, TRUE)
placed_sign.update_integrity(get_integrity())
placed_sign.setDir(dir)
placed_sign.find_and_hang_on_wall(TRUE, placed_sign.knock_down_callback)
placed_sign.find_and_hang_on_wall()
qdel(src)
return ITEM_INTERACT_SUCCESS

View File

@@ -28,7 +28,7 @@
/// The range of the paintings effect
var/range = 7
/obj/structure/sign/painting/eldritch/Initialize(mapload, dir, building)
/obj/structure/sign/painting/eldritch/Initialize(mapload)
. = ..()
if(ispath(applied_status_effect))
var/static/list/connections = list(COMSIG_ATOM_ENTERED = PROC_REF(apply_status_effect))
@@ -177,7 +177,7 @@
/obj/item/food/grown/harebell,
)
/obj/structure/sign/painting/eldritch/vines/Initialize(mapload, dir, building)
/obj/structure/sign/painting/eldritch/vines/Initialize(mapload)
. = ..()
new /datum/spacevine_controller(get_turf(src), mutations, 0, 10)

View File

@@ -713,11 +713,9 @@
/obj/structure/sign/painting/get_save_vars()
return ..() - NAMEOF(src, icon)
/obj/structure/sign/painting/Initialize(mapload, dir, building)
/obj/structure/sign/painting/Initialize(mapload)
. = ..()
SSpersistent_paintings.painting_frames += src
if(dir)
setDir(dir)
/obj/structure/sign/painting/Destroy()
. = ..()
@@ -732,12 +730,8 @@
else
return ..()
/obj/structure/sign/painting/knock_down(mob/living/user)
var/turf/drop_turf
if(user)
drop_turf = get_turf(user)
else
drop_turf = drop_location()
/obj/structure/sign/painting/atom_deconstruct(disassembled)
var/turf/drop_turf = drop_location()
current_canvas?.forceMove(drop_turf)
var/obj/item/wallframe/frame = new wallframe_type(drop_turf)
frame.update_integrity(get_integrity()) //Transfer how damaged it is.

View File

@@ -90,13 +90,11 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm)
/obj/machinery/airalarm/get_save_vars()
return ..() - NAMEOF(src, name)
/obj/machinery/airalarm/Initialize(mapload, ndir, nbuild)
/obj/machinery/airalarm/Initialize(mapload)
. = ..()
set_wires(new /datum/wires/airalarm(src))
if(ndir)
setDir(ndir)
if(nbuild)
if(!mapload)
buildstage = AIR_ALARM_BUILD_NO_CIRCUIT
set_panel_open(TRUE)
@@ -131,6 +129,7 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm)
))
GLOB.air_alarms += src
if(mapload)
find_and_hang_on_wall()
register_context()
check_enviroment()

View File

@@ -34,12 +34,11 @@
/// Trophies from persistence have a good chance to be dusted if removal is attempted, though rarely it pays off.
var/persistence_loaded_fish = FALSE
/obj/structure/fish_mount/Initialize(mapload, floor_to_wall_dir)
/obj/structure/fish_mount/Initialize(mapload)
. = ..()
//Mounted fish shouldn't flop. It should also show size and weight to everyone.
add_traits(list(TRAIT_STOP_FISH_FLOPPING, TRAIT_EXAMINE_FISH), INNATE_TRAIT)
if(floor_to_wall_dir)
setDir(floor_to_wall_dir)
if(mapload)
find_and_hang_on_wall()
if(!persistence_id)
return

View File

@@ -31,6 +31,7 @@
/obj/machinery/ticket_machine/Initialize(mapload)
. = ..()
update_appearance()
if(mapload)
find_and_hang_on_wall()
/obj/machinery/ticket_machine/Destroy()

View File

@@ -73,13 +73,11 @@
var/art_value = OK_ART
var/can_decon = TRUE
/obj/structure/sign/picture_frame/Initialize(mapload, dir, building)
/obj/structure/sign/picture_frame/Initialize(mapload)
. = ..()
AddElement(/datum/element/art, art_value)
if (!SSpersistence.initialized)
LAZYADD(SSpersistence.queued_photo_frames, src)
if(dir)
setDir(dir)
/obj/structure/sign/picture_frame/Destroy()
LAZYREMOVE(SSpersistence.queued_photo_frames, src)

View File

@@ -261,6 +261,7 @@
AddElement(/datum/element/contextual_screentip_bare_hands, rmb_text = "Toggle interface lock")
AddElement(/datum/element/contextual_screentip_mob_typechecks, hovering_mob_typechecks)
if(mapload)
find_and_hang_on_wall()
/obj/machinery/power/apc/Destroy()

View File

@@ -118,8 +118,12 @@
RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater))
AddElement(/datum/element/atmos_sensitive, mapload)
AddElement(/datum/element/contextual_screentip_bare_hands, rmb_text = "Remove bulb")
if(mapload)
find_and_hang_on_wall()
/obj/machinery/light/find_and_hang_on_wall()
if(break_if_moved)
find_and_hang_on_wall(custom_drop_callback = CALLBACK(src, PROC_REF(knock_down)))
return ..()
/obj/machinery/light/post_machine_initialize()
. = ..()
@@ -141,6 +145,11 @@
QDEL_NULL(cell)
return ..()
/obj/machinery/light/Exited(atom/movable/gone, direction)
. = ..()
if(gone == cell)
cell = null
/obj/machinery/light/setDir(newdir)
. = ..()
set_light(l_dir = REVERSE_DIR(dir))
@@ -407,34 +416,26 @@
electrocute_mob(user, get_area(src), src, (rand(7,10) * 0.1), TRUE)
/obj/machinery/light/on_deconstruction(disassembled)
var/obj/structure/light_construct/new_light = null
var/current_stage = 2
if(!disassembled)
current_stage = 1
var/atom/drop_point = drop_location()
var/obj/item/wallframe/light_fixture/frame = null
switch(fitting)
if("tube")
new_light = new /obj/structure/light_construct(loc)
new_light.icon_state = "tube-construct-stage[current_stage]"
frame = new /obj/item/wallframe/light_fixture(drop_point)
if("bulb")
new_light = new /obj/structure/light_construct/small(loc)
new_light.icon_state = "bulb-construct-stage[current_stage]"
new_light.setDir(dir)
new_light.stage = current_stage
frame = new /obj/item/wallframe/light_fixture/small(drop_point)
if(!disassembled)
new_light.take_damage(new_light.max_integrity * 0.5, sound_effect=FALSE)
frame.take_damage(frame.max_integrity * 0.5, sound_effect = FALSE)
if(status != LIGHT_BROKEN)
break_light_tube()
if(status != LIGHT_EMPTY)
drop_light_tube()
new /obj/item/stack/cable_coil(loc, 1, "red")
transfer_fingerprints_to(new_light)
transfer_fingerprints_to(frame)
var/obj/item/stock_parts/power_store/real_cell = get_cell()
if(!QDELETED(real_cell))
new_light.cell = real_cell
real_cell.forceMove(new_light)
cell = null
real_cell.forceMove(drop_point)
/obj/machinery/light/attacked_by(obj/item/attacking_object, mob/living/user, list/modifiers, list/attack_modifiers)
. = ..()
@@ -716,23 +717,6 @@
continue
INVOKE_ASYNC(src, PROC_REF(flicker))
/**
* All the effects that occur when a light falls off a wall that it was hung onto.
*/
/obj/machinery/light/proc/knock_down()
if (fitting == "bulb")
new /obj/item/wallframe/light_fixture/small(drop_location())
else
new /obj/item/wallframe/light_fixture(drop_location())
new /obj/item/stack/cable_coil(drop_location(), 1, "red")
if(status != LIGHT_BROKEN)
break_light_tube(FALSE)
if(status != LIGHT_EMPTY)
drop_light_tube()
if(cell)
cell.forceMove(drop_location())
qdel(src)
/obj/machinery/light/floor
name = "floor light"
desc = "A lightbulb you can walk on without breaking it, amazing."

View File

@@ -28,10 +28,9 @@
fire = 80
acid = 50
/obj/structure/light_construct/Initialize(mapload, ndir, building)
/obj/structure/light_construct/Initialize(mapload)
. = ..()
if(building)
setDir(ndir)
if(mapload)
find_and_hang_on_wall()
/obj/structure/light_construct/Destroy()
@@ -107,11 +106,9 @@
return
to_chat(user, span_notice("You begin deconstructing [src]..."))
if (tool.use_tool(src, user, 30, volume=50))
new /obj/item/stack/sheet/iron(drop_location(), sheets_refunded)
user.visible_message(span_notice("[user.name] deconstructs [src]."), \
span_notice("You deconstruct [src]."), span_hear("You hear a ratchet."))
playsound(src, 'sound/items/deconstruct.ogg', 75, TRUE)
qdel(src)
return
if(istype(tool, /obj/item/stack/cable_coil))
@@ -159,10 +156,12 @@
/obj/structure/light_construct/blob_act(obj/structure/blob/attacking_blob)
if(attacking_blob && attacking_blob.loc == loc)
qdel(src)
deconstruct(FALSE)
/obj/structure/light_construct/atom_deconstruct(disassembled = TRUE)
/obj/structure/light_construct/atom_deconstruct(disassembled)
new /obj/item/stack/sheet/iron(loc, sheets_refunded)
if(stage == LIGHT_CONSTRUCT_WIRED)
new /obj/item/stack/cable_coil(drop_location(), 1, "red")
/obj/structure/light_construct/small
name = "small light fixture frame"

View File

@@ -353,6 +353,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/reagent_dispensers/wall/peppertank, 3
. = ..()
if(prob(1))
desc = "IT'S PEPPER TIME, BITCH!"
if(mapload)
find_and_hang_on_wall()
/obj/structure/reagent_dispensers/water_cooler
@@ -611,6 +612,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/reagent_dispensers/wall/virusfood, 30
/obj/structure/reagent_dispensers/wall/virusfood/Initialize(mapload)
. = ..()
if(mapload)
find_and_hang_on_wall()
/obj/structure/reagent_dispensers/cooking_oil

View File

@@ -164,6 +164,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/keycard_auth/wall_mounted, 26)
/obj/machinery/keycard_auth/wall_mounted/Initialize(mapload)
. = ..()
if(mapload)
find_and_hang_on_wall()
GLOBAL_VAR_INIT(emergency_access, FALSE)

View File

@@ -103,10 +103,10 @@
to_chat(user, span_warning("You are too far away to activate the button!"))
/obj/machinery/button/transport/tram/setup_device()
. = ..()
var/obj/item/assembly/control/transport/call_button/tram_device = device
tram_device.id = id
if(istype(tram_device))
tram_device.specific_transport_id = specific_transport_id
return ..()
/obj/machinery/button/transport/tram/examine(mob/user)
. = ..()

View File

@@ -27,14 +27,14 @@
click_wrapper(attacker, to_smack)
TEST_ASSERT_NOTEQUAL(to_smack.get_integrity(), to_smack.max_integrity, "The barricade should have taken damage a from a non-combat-mode click.")
/// Tests that common tool interactions are possible still, by attempting to open the panel of an air alarm.
/// Tests that common tool interactions are possible still, by attempting to open the panel of an techfab.
/datum/unit_test/machinery_tool_interaction
/datum/unit_test/machinery_tool_interaction/Run()
var/mob/living/carbon/human/consistent/attacker = EASY_ALLOCATE()
var/obj/item/screwdriver/screwdriver = EASY_ALLOCATE()
var/obj/machinery/airalarm/to_smack = EASY_ALLOCATE()
var/obj/machinery/rnd/production/to_smack = EASY_ALLOCATE()
attacker.put_in_active_hand(screwdriver, forced = TRUE)
click_wrapper(attacker, to_smack)
TEST_ASSERT_EQUAL(to_smack.get_integrity(), to_smack.max_integrity, "The air alarm took damage when interacted with a screwdriver.")
TEST_ASSERT(to_smack.panel_open, "The air alarm should have opened its panel after being interacted with a screwdriver.")
TEST_ASSERT_EQUAL(to_smack.get_integrity(), to_smack.max_integrity, "The techfab took damage when interacted with a screwdriver.")
TEST_ASSERT(to_smack.panel_open, "The techfab should have opened its panel after being interacted with a screwdriver.")