mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 12:41:09 +01:00
Player-craftable Trapdoors (#68920)
Makes trapdoors player-craftable. Player-crafted trapdoors have a tiny outline as well as being visible on examine. (Mapped in trapdoors have conspicuous = FALSE by default) Trapdoors can be made by using a trapdoor kit (crafted via player crafting menu) on openspace. Trapdoor electronics / assembly can be made via autolathe or engineering lathe. A preloaded trapdoor remote (optional) can be made by crafting the electronics with a compact remote (from science lathe / circuit lab) and some cable coil. Also allows unlinking trapdoors via a multitool, decreased trapdoor link range, and made some changes to trapdoor code. Added change: Trapdoors now don't break with just a crowbar Why It's Good For The Game Trapdoors currently can only be added in by mappers and this would allow for a lot of interesting contraptions, while having player-crafted trapdoors be detectable provides some counterplay Picture trapdoorlookdemo Changelog cl add: You can now make trapdoors. Craft a trapdoor kit and use it on an openspace tile to make one, then link and activate it with some trapdoor electronics (printable at an autolathe or the engineering lathe) and optionally a trapdoor remote (crafted in personal crafting menu). qol: You can now unlink trapdoors by using a multitool on them. balance: Trapdoors now won't break if you just crowbar them. You need to block them from closing, such as with a lattice, cover it up with a wall, or fully destroy the floor tile its on to get rid of them. /cl
This commit is contained in:
@@ -759,6 +759,29 @@
|
||||
time = 20 SECONDS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/trapdoor_kit
|
||||
name = "Trapdoor Construction Kit"
|
||||
result = /obj/item/trapdoor_kit
|
||||
reqs = list(/obj/item/stack/sheet/iron = 4,
|
||||
/obj/item/stack/rods = 4,
|
||||
/obj/item/stack/cable_coil = 10,
|
||||
/obj/item/stock_parts/manipulator = 2,
|
||||
/obj/item/assembly/signaler = 1)
|
||||
tool_behaviors = list(TOOL_WELDER, TOOL_SCREWDRIVER)
|
||||
time = 10 SECONDS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/trapdoor_remote
|
||||
name = "Trapdoor Remote"
|
||||
result = /obj/item/trapdoor_remote/preloaded // since its useless without its assembly just require an assembly to craft it
|
||||
reqs = list(
|
||||
/obj/item/compact_remote = 1,
|
||||
/obj/item/stack/cable_coil = 5,
|
||||
/obj/item/assembly/trapdoor = 1)
|
||||
tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
time = 5 SECONDS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/mousetrap
|
||||
name = "Mouse Trap"
|
||||
result = /obj/item/assembly/mousetrap
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
///makes this file more legible
|
||||
#define IS_OPEN(parent) isgroundlessturf(parent)
|
||||
///distance a trapdoor will accept a link request.
|
||||
#define TRAPDOOR_LINKING_SEARCH_RANGE 7
|
||||
#define TRAPDOOR_LINKING_SEARCH_RANGE 4
|
||||
|
||||
/**
|
||||
* ## trapdoor component!
|
||||
@@ -15,12 +15,21 @@
|
||||
var/obj/item/assembly/trapdoor/assembly
|
||||
///path of the turf this should change into when the assembly is pulsed. needed for openspace trapdoors knowing what to turn back into
|
||||
var/trapdoor_turf_path
|
||||
/// is this trapdoor "conspicuous" (ie. it gets examine text and overlay added)
|
||||
var/conspicuous
|
||||
/// overlay that makes trapdoors more obvious
|
||||
var/static/trapdoor_overlay
|
||||
|
||||
/datum/component/trapdoor/Initialize(starts_open, trapdoor_turf_path, assembly)
|
||||
/datum/component/trapdoor/Initialize(starts_open, trapdoor_turf_path, assembly, conspicuous = TRUE)
|
||||
if(!isopenturf(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
src.conspicuous = conspicuous
|
||||
src.assembly = assembly
|
||||
|
||||
if(!trapdoor_overlay)
|
||||
trapdoor_overlay = mutable_appearance('icons/turf/overlays.dmi', "border_black", ABOVE_NORMAL_TURF_LAYER)
|
||||
|
||||
if(IS_OPEN(parent))
|
||||
openspace_trapdoor_setup(trapdoor_turf_path, assembly)
|
||||
else
|
||||
@@ -38,14 +47,19 @@
|
||||
src.trapdoor_turf_path = parent.type
|
||||
if(assembly && assembly.stored_decals.len)
|
||||
reapply_all_decals()
|
||||
if(conspicuous)
|
||||
var/turf/parent_turf = parent
|
||||
parent_turf.add_overlay(trapdoor_overlay)
|
||||
|
||||
/datum/component/trapdoor/RegisterWithParent()
|
||||
. = ..()
|
||||
RegisterSignal(parent, COMSIG_TURF_CHANGE, .proc/turf_changed_pre)
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
|
||||
if(!src.assembly)
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_TRAPDOOR_LINK, .proc/on_link_requested)
|
||||
else
|
||||
RegisterSignal(assembly, COMSIG_ASSEMBLY_PULSED, .proc/toggle_trapdoor)
|
||||
RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), .proc/try_unlink)
|
||||
|
||||
/datum/component/trapdoor/UnregisterFromParent()
|
||||
. = ..()
|
||||
@@ -53,6 +67,33 @@
|
||||
if(assembly)
|
||||
UnregisterSignal(assembly, COMSIG_ASSEMBLY_PULSED)
|
||||
UnregisterSignal(parent, COMSIG_TURF_CHANGE)
|
||||
UnregisterSignal(parent, COMSIG_PARENT_EXAMINE)
|
||||
UnregisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL))
|
||||
|
||||
/datum/component/trapdoor/proc/try_unlink(turf/source, mob/user, obj/item/tool)
|
||||
SIGNAL_HANDLER
|
||||
if(!assembly)
|
||||
return
|
||||
if(IS_OPEN(parent))
|
||||
source.balloon_alert(user, "can't unlink trapdoor when its open")
|
||||
return
|
||||
source.balloon_alert(user, "unlinking trapdoor")
|
||||
INVOKE_ASYNC(src, .proc/async_try_unlink, source, user, tool)
|
||||
return
|
||||
|
||||
/datum/component/trapdoor/proc/async_try_unlink(turf/source, mob/user, obj/item/tool)
|
||||
if(!do_after(user, 5 SECONDS, target=source))
|
||||
return
|
||||
if(IS_OPEN(parent))
|
||||
source.balloon_alert(user, "can't unlink trapdoor when its open")
|
||||
return
|
||||
assembly.linked = FALSE
|
||||
assembly.stored_decals = list()
|
||||
UnregisterSignal(assembly, COMSIG_ASSEMBLY_PULSED)
|
||||
UnregisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL))
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_TRAPDOOR_LINK, .proc/on_link_requested)
|
||||
assembly = null
|
||||
source.balloon_alert(user, "trapdoor unlinked")
|
||||
|
||||
/datum/component/trapdoor/proc/decal_detached(datum/source, description, cleanable, directional, pic)
|
||||
SIGNAL_HANDLER
|
||||
@@ -76,13 +117,14 @@
|
||||
///called by linking remotes to tie an assembly to the trapdoor
|
||||
/datum/component/trapdoor/proc/on_link_requested(datum/source, obj/item/assembly/trapdoor/assembly)
|
||||
SIGNAL_HANDLER
|
||||
if(get_dist(parent, assembly) > TRAPDOOR_LINKING_SEARCH_RANGE)
|
||||
if(get_dist(parent, assembly) > TRAPDOOR_LINKING_SEARCH_RANGE || assembly.linked)
|
||||
return
|
||||
. = LINKED_UP
|
||||
src.assembly = assembly
|
||||
assembly.linked = TRUE
|
||||
UnregisterSignal(SSdcs, COMSIG_GLOB_TRAPDOOR_LINK)
|
||||
RegisterSignal(assembly, COMSIG_ASSEMBLY_PULSED, .proc/toggle_trapdoor)
|
||||
RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), .proc/try_unlink)
|
||||
|
||||
///signal called by our assembly being pulsed
|
||||
/datum/component/trapdoor/proc/toggle_trapdoor(datum/source)
|
||||
@@ -96,14 +138,18 @@
|
||||
/datum/component/trapdoor/proc/turf_changed_pre(datum/source, path, new_baseturfs, flags, post_change_callbacks)
|
||||
SIGNAL_HANDLER
|
||||
var/turf/open/dying_trapdoor = parent
|
||||
if((!IS_OPEN(dying_trapdoor) && !IS_OPEN(path)) || path == /turf/open/floor/plating) //not a process of the trapdoor, so this trapdoor has been destroyed
|
||||
if((flags & CHANGETURF_TRAPDOOR_INDUCED) == 0) //not a process of the trapdoor
|
||||
if(!IS_OPEN(parent) && !ispath(path, /turf/closed) && !ispath(path, /turf/open/openspace)) // allow people to place tiles on plating / change tiles without breaking the trapdoor
|
||||
post_change_callbacks += CALLBACK(src, /datum/component/trapdoor.proc/carry_over_trapdoor, path, conspicuous, assembly)
|
||||
return
|
||||
// otherwise, break trapdoor
|
||||
dying_trapdoor.visible_message(span_warning("The trapdoor mechanism in [dying_trapdoor] is broken!"))
|
||||
if(assembly)
|
||||
assembly.linked = FALSE
|
||||
assembly.stored_decals.Cut()
|
||||
assembly = null
|
||||
return
|
||||
post_change_callbacks += CALLBACK(assembly, /obj/item/assembly/trapdoor.proc/carry_over_trapdoor, trapdoor_turf_path)
|
||||
post_change_callbacks += CALLBACK(src, /datum/component/trapdoor.proc/carry_over_trapdoor, trapdoor_turf_path, conspicuous, assembly)
|
||||
|
||||
/**
|
||||
* ## carry_over_trapdoor
|
||||
@@ -111,8 +157,18 @@
|
||||
* applies the trapdoor to the new turf (created by the last trapdoor)
|
||||
* apparently callbacks with arguments on invoke and the callback itself have the callback args go first. interesting!
|
||||
*/
|
||||
/obj/item/assembly/trapdoor/proc/carry_over_trapdoor(trapdoor_turf_path, turf/new_turf)
|
||||
new_turf.AddComponent(/datum/component/trapdoor, FALSE, trapdoor_turf_path, src)
|
||||
/datum/component/trapdoor/proc/carry_over_trapdoor(trapdoor_turf_path, conspicuous, assembly, turf/new_turf)
|
||||
new_turf.AddComponent(/datum/component/trapdoor, FALSE, trapdoor_turf_path, assembly, conspicuous)
|
||||
|
||||
/**
|
||||
* ## on_examine
|
||||
*
|
||||
* examine message for conspicuous trapdoors that makes it obvious
|
||||
*/
|
||||
/datum/component/trapdoor/proc/on_examine(datum/source, mob/user, list/examine_text)
|
||||
SIGNAL_HANDLER
|
||||
if(conspicuous)
|
||||
examine_text += "There seems to be a tiny gap around this tile with some wires that you might be able to pulse with a <b>multitool</b>."
|
||||
|
||||
/**
|
||||
* ## try_opening
|
||||
@@ -127,7 +183,7 @@
|
||||
RegisterSignal(parent, COMSIG_TURF_DECAL_DETACHED, .proc/decal_detached)
|
||||
playsound(trapdoor_turf, 'sound/machines/trapdoor/trapdoor_open.ogg', 50)
|
||||
trapdoor_turf.visible_message(span_warning("[trapdoor_turf] swings open!"))
|
||||
trapdoor_turf.ChangeTurf(/turf/open/openspace, flags = CHANGETURF_INHERIT_AIR)
|
||||
trapdoor_turf.ChangeTurf(/turf/open/openspace, flags = CHANGETURF_INHERIT_AIR | CHANGETURF_TRAPDOOR_INDUCED)
|
||||
|
||||
/**
|
||||
* ## try_closing
|
||||
@@ -143,7 +199,7 @@
|
||||
return
|
||||
playsound(trapdoor_turf, 'sound/machines/trapdoor/trapdoor_shut.ogg', 50)
|
||||
trapdoor_turf.visible_message(span_warning("The trapdoor mechanism in [trapdoor_turf] swings shut!"))
|
||||
trapdoor_turf.ChangeTurf(trapdoor_turf_path, flags = CHANGETURF_INHERIT_AIR)
|
||||
trapdoor_turf.ChangeTurf(trapdoor_turf_path, flags = CHANGETURF_INHERIT_AIR | CHANGETURF_TRAPDOOR_INDUCED)
|
||||
|
||||
#undef IS_OPEN
|
||||
|
||||
@@ -280,3 +336,39 @@
|
||||
/obj/item/trapdoor_remote/preloaded/Initialize(mapload)
|
||||
. = ..()
|
||||
internals = new(src)
|
||||
|
||||
/// trapdoor parts kit, allows trapdoors to be made by players
|
||||
/obj/item/trapdoor_kit
|
||||
name = "trapdoor parts kit"
|
||||
desc = "A kit containing all the parts needed to build a trapdoor. Can only be used on open space."
|
||||
icon = 'icons/obj/improvised.dmi'
|
||||
icon_state = "kitsuitcase"
|
||||
var/in_use = FALSE
|
||||
|
||||
/obj/item/trapdoor_kit/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/openspace_item_click_handler)
|
||||
|
||||
/obj/item/trapdoor_kit/handle_openspace_click(turf/target, mob/user, proximity_flag, click_parameters)
|
||||
afterattack(target, user, proximity_flag, click_parameters)
|
||||
|
||||
/obj/item/trapdoor_kit/afterattack(atom/target, mob/user, proximity_flag)
|
||||
. = ..()
|
||||
if(!proximity_flag)
|
||||
return
|
||||
var/turf/target_turf = get_turf(target)
|
||||
if(!isopenspaceturf(target_turf))
|
||||
return
|
||||
in_use = TRUE
|
||||
balloon_alert(user, "constructing trapdoor")
|
||||
if(!do_after(user, 5 SECONDS, target = target))
|
||||
in_use = FALSE
|
||||
return
|
||||
in_use = FALSE
|
||||
if(!isopenspaceturf(target_turf)) // second check to make sure nothing changed during constructions
|
||||
return
|
||||
var/turf/new_turf = target_turf.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
new_turf.AddComponent(/datum/component/trapdoor, starts_open = FALSE, conspicuous = TRUE)
|
||||
balloon_alert(user, "trapdoor constructed")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user