mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 01:34:01 +00:00
* Fixes blockers blocking themselves + cleanup (#59808) * Fixes blockers blocking themselves + cleanup Co-authored-by: Rohesie <rohesie@gmail.com>
462 lines
16 KiB
Plaintext
462 lines
16 KiB
Plaintext
#define CONSTRUCTION_PANEL_OPEN 1 //Maintenance panel is open, still functioning
|
|
#define CONSTRUCTION_NO_CIRCUIT 2 //Circuit board removed, can safely weld apart
|
|
#define DEFAULT_STEP_TIME 20 /// default time for each step
|
|
|
|
/obj/machinery/door/firedoor
|
|
name = "firelock"
|
|
desc = "Apply crowbar."
|
|
icon = 'icons/obj/doors/Doorfireglass.dmi' //ICON OVERRIDEN IN SKYRAT AESTHETICS - SEE MODULE
|
|
icon_state = "door_open"
|
|
opacity = FALSE
|
|
density = FALSE
|
|
max_integrity = 300
|
|
resistance_flags = FIRE_PROOF
|
|
heat_proof = TRUE
|
|
glass = TRUE
|
|
sub_door = TRUE
|
|
explosion_block = 1
|
|
safe = FALSE
|
|
layer = BELOW_OPEN_DOOR_LAYER
|
|
closingLayer = BELOW_OPEN_DOOR_LAYER //SKYRAT EDIT CHANGE - AESTHETICS - ORIGINAL: CLOSED_FIREDOOR_LAYER
|
|
assemblytype = /obj/structure/firelock_frame
|
|
armor = list(MELEE = 10, BULLET = 30, LASER = 20, ENERGY = 20, BOMB = 30, BIO = 100, RAD = 100, FIRE = 95, ACID = 70)
|
|
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
|
|
var/nextstate = null
|
|
var/boltslocked = TRUE
|
|
var/list/affecting_areas
|
|
var/being_held_open = FALSE
|
|
|
|
/obj/machinery/door/firedoor/Initialize()
|
|
. = ..()
|
|
CalculateAffectingAreas()
|
|
|
|
/obj/machinery/door/firedoor/examine(mob/user)
|
|
. = ..()
|
|
if(!density)
|
|
. += span_notice("It is open, but could be <b>pried</b> closed.")
|
|
else if(!welded)
|
|
. += span_notice("It is closed, but could be <b>pried</b> open.")
|
|
. += span_notice("Hold the firelock temporarily open by prying it with <i>left-click</i> and standing next to it.")
|
|
. += span_notice("Prying by <i>right-clicking</i> the firelock will open it permanently.")
|
|
. += span_notice("Deconstruction would require it to be <b>welded</b> shut.")
|
|
else if(boltslocked)
|
|
. += span_notice("It is <i>welded</i> shut. The floor bolts have been locked by <b>screws</b>.")
|
|
else
|
|
. += span_notice("The bolt locks have been <i>unscrewed</i>, but the bolts themselves are still <b>wrenched</b> to the floor.")
|
|
|
|
/obj/machinery/door/firedoor/proc/CalculateAffectingAreas()
|
|
remove_from_areas()
|
|
affecting_areas = get_adjacent_open_areas(src) | get_area(src)
|
|
for(var/I in affecting_areas)
|
|
var/area/A = I
|
|
LAZYADD(A.firedoors, src)
|
|
|
|
/obj/machinery/door/firedoor/closed
|
|
icon_state = "door_closed"
|
|
density = TRUE
|
|
|
|
//see also turf/AfterChange for adjacency shennanigans
|
|
|
|
/obj/machinery/door/firedoor/proc/remove_from_areas()
|
|
if(affecting_areas)
|
|
for(var/I in affecting_areas)
|
|
var/area/A = I
|
|
LAZYREMOVE(A.firedoors, src)
|
|
|
|
/obj/machinery/door/firedoor/Destroy()
|
|
remove_from_areas()
|
|
affecting_areas.Cut()
|
|
return ..()
|
|
|
|
/obj/machinery/door/firedoor/Bumped(atom/movable/AM)
|
|
if(panel_open || operating)
|
|
return
|
|
if(!density)
|
|
return ..()
|
|
return FALSE
|
|
|
|
/obj/machinery/door/firedoor/bumpopen(mob/living/user)
|
|
return FALSE //No bumping to open, not even in mechs
|
|
|
|
/obj/machinery/door/firedoor/power_change()
|
|
. = ..()
|
|
INVOKE_ASYNC(src, .proc/latetoggle)
|
|
|
|
/* /obj/machinery/door/firedoor/attack_hand(mob/user, list/modifiers)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
if(operating || !density)
|
|
return
|
|
user.changeNext_move(CLICK_CD_MELEE)
|
|
|
|
user.visible_message("<span class='notice'>[user] bangs on \the [src].</span>", \
|
|
"<span class='notice'>You bang on \the [src].</span>")
|
|
playsound(loc, 'sound/effects/glassknock.ogg', 10, FALSE, frequency = 32000) */ // SKYRAT EDIT CHANGE - MOVED TO modular_skyrat\master_files\game\machinery\doors\firedoor.dm
|
|
|
|
/obj/machinery/door/firedoor/attackby(obj/item/C, mob/user, params)
|
|
add_fingerprint(user)
|
|
if(operating)
|
|
return
|
|
if(welded)
|
|
if(C.tool_behaviour == TOOL_WRENCH)
|
|
if(boltslocked)
|
|
to_chat(user, span_notice("There are screws locking the bolts in place!"))
|
|
return
|
|
C.play_tool_sound(src)
|
|
user.visible_message(span_notice("[user] starts undoing [src]'s bolts..."), \
|
|
span_notice("You start unfastening [src]'s floor bolts..."))
|
|
if(!C.use_tool(src, user, DEFAULT_STEP_TIME))
|
|
return
|
|
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
|
user.visible_message(span_notice("[user] unfastens [src]'s bolts."), \
|
|
span_notice("You undo [src]'s floor bolts."))
|
|
deconstruct(TRUE)
|
|
return
|
|
if(C.tool_behaviour == TOOL_SCREWDRIVER)
|
|
user.visible_message(span_notice("[user] [boltslocked ? "unlocks" : "locks"] [src]'s bolts."), \
|
|
span_notice("You [boltslocked ? "unlock" : "lock"] [src]'s floor bolts."))
|
|
C.play_tool_sound(src)
|
|
boltslocked = !boltslocked
|
|
return
|
|
return ..()
|
|
|
|
/obj/machinery/door/firedoor/try_to_activate_door(mob/user)
|
|
return
|
|
|
|
/obj/machinery/door/firedoor/try_to_weld(obj/item/weldingtool/W, mob/user)
|
|
if(!W.tool_start_check(user, amount=0))
|
|
return
|
|
user.visible_message(span_notice("[user] starts [welded ? "unwelding" : "welding"] [src]."), span_notice("You start welding [src]."))
|
|
if(W.use_tool(src, user, DEFAULT_STEP_TIME, volume=50))
|
|
welded = !welded
|
|
user.visible_message(span_danger("[user] [welded?"welds":"unwelds"] [src]."), span_notice("You [welded ? "weld" : "unweld"] [src]."))
|
|
log_game("[key_name(user)] [welded ? "welded":"unwelded"] firedoor [src] with [W] at [AREACOORD(src)]")
|
|
update_appearance()
|
|
|
|
/// We check for adjacency when using the primary attack.
|
|
/obj/machinery/door/firedoor/try_to_crowbar(obj/item/acting_object, mob/user)
|
|
if(welded || operating)
|
|
return
|
|
|
|
if(density)
|
|
being_held_open = TRUE
|
|
user.balloon_alert_to_viewers("holding [src] open", "holding [src] open")
|
|
open()
|
|
if(QDELETED(user))
|
|
being_held_open = FALSE
|
|
return
|
|
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/handle_held_open_adjacency)
|
|
RegisterSignal(user, COMSIG_LIVING_SET_BODY_POSITION, .proc/handle_held_open_adjacency)
|
|
RegisterSignal(user, COMSIG_PARENT_QDELETING, .proc/handle_held_open_adjacency)
|
|
handle_held_open_adjacency(user)
|
|
else
|
|
close()
|
|
|
|
/// A simple toggle for firedoors between on and off
|
|
/obj/machinery/door/firedoor/try_to_crowbar_secondary(obj/item/acting_object, mob/user)
|
|
if(welded || operating)
|
|
return
|
|
|
|
if(density)
|
|
open()
|
|
else
|
|
close()
|
|
|
|
/obj/machinery/door/firedoor/proc/handle_held_open_adjacency(mob/user)
|
|
SIGNAL_HANDLER
|
|
|
|
var/mob/living/living_user = user
|
|
if(!QDELETED(user) && Adjacent(user) && isliving(user) && (living_user.body_position == STANDING_UP))
|
|
return
|
|
being_held_open = FALSE
|
|
INVOKE_ASYNC(src, .proc/close)
|
|
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
|
UnregisterSignal(user, COMSIG_LIVING_SET_BODY_POSITION)
|
|
UnregisterSignal(user, COMSIG_PARENT_QDELETING)
|
|
if(user)
|
|
user.balloon_alert_to_viewers("released [src]", "released [src]")
|
|
|
|
/obj/machinery/door/firedoor/attack_ai(mob/user)
|
|
add_fingerprint(user)
|
|
if(welded || operating || machine_stat & NOPOWER)
|
|
return TRUE
|
|
if(density)
|
|
open()
|
|
else
|
|
close()
|
|
return TRUE
|
|
|
|
/obj/machinery/door/firedoor/attack_robot(mob/user)
|
|
return attack_ai(user)
|
|
|
|
/obj/machinery/door/firedoor/attack_alien(mob/user, list/modifiers)
|
|
add_fingerprint(user)
|
|
if(welded)
|
|
to_chat(user, span_warning("[src] refuses to budge!"))
|
|
return
|
|
open()
|
|
|
|
/obj/machinery/door/firedoor/do_animate(animation)
|
|
switch(animation)
|
|
if("opening")
|
|
flick("door_opening", src)
|
|
if("closing")
|
|
flick("door_closing", src)
|
|
|
|
/obj/machinery/door/firedoor/update_icon_state()
|
|
. = ..()
|
|
icon_state = "[base_icon_state]_[density ? "closed" : "open"]"
|
|
|
|
/obj/machinery/door/firedoor/update_overlays()
|
|
. = ..()
|
|
if(!welded)
|
|
return
|
|
. += density ? "welded" : "welded_open"
|
|
|
|
/obj/machinery/door/firedoor/open()
|
|
. = ..()
|
|
latetoggle()
|
|
|
|
/obj/machinery/door/firedoor/close()
|
|
if(HAS_TRAIT(loc, TRAIT_FIREDOOR_STOP))
|
|
return
|
|
. = ..()
|
|
latetoggle()
|
|
|
|
/obj/machinery/door/firedoor/deconstruct(disassembled = TRUE)
|
|
if(!(flags_1 & NODECONSTRUCT_1))
|
|
var/turf/T = get_turf(src)
|
|
if(disassembled || prob(40))
|
|
var/obj/structure/firelock_frame/F = new assemblytype(T)
|
|
if(disassembled)
|
|
F.constructionStep = CONSTRUCTION_PANEL_OPEN
|
|
else
|
|
F.constructionStep = CONSTRUCTION_NO_CIRCUIT
|
|
F.update_integrity(F.max_integrity * 0.5)
|
|
F.update_appearance()
|
|
else
|
|
new /obj/item/electronics/firelock (T)
|
|
qdel(src)
|
|
|
|
|
|
/obj/machinery/door/firedoor/proc/latetoggle()
|
|
if(operating || machine_stat & NOPOWER || !nextstate)
|
|
return
|
|
switch(nextstate)
|
|
if(FIREDOOR_OPEN)
|
|
nextstate = null
|
|
open()
|
|
if(FIREDOOR_CLOSED)
|
|
nextstate = null
|
|
close()
|
|
|
|
/obj/machinery/door/firedoor/border_only
|
|
icon = 'icons/obj/doors/edge_Doorfire.dmi'
|
|
can_crush = FALSE
|
|
flags_1 = ON_BORDER_1
|
|
CanAtmosPass = ATMOS_PASS_PROC
|
|
glass = FALSE
|
|
|
|
/obj/machinery/door/firedoor/border_only/closed
|
|
icon_state = "door_closed"
|
|
opacity = TRUE
|
|
density = TRUE
|
|
|
|
/obj/machinery/door/firedoor/border_only/Initialize()
|
|
. = ..()
|
|
|
|
var/static/list/loc_connections = list(
|
|
COMSIG_ATOM_EXIT = .proc/on_exit,
|
|
)
|
|
|
|
AddElement(/datum/element/connect_loc, loc_connections)
|
|
|
|
/obj/machinery/door/firedoor/border_only/CanAllowThrough(atom/movable/mover, border_dir)
|
|
. = ..()
|
|
if(!(border_dir == dir)) //Make sure looking at appropriate border
|
|
return TRUE
|
|
|
|
/obj/machinery/door/firedoor/border_only/proc/on_exit(datum/source, atom/movable/leaving, direction)
|
|
SIGNAL_HANDLER
|
|
if(leaving == src)
|
|
return // Let's not block ourselves.
|
|
|
|
if(direction == dir && density)
|
|
leaving.Bump(src)
|
|
return COMPONENT_ATOM_BLOCK_EXIT
|
|
|
|
/obj/machinery/door/firedoor/border_only/CanAtmosPass(turf/T)
|
|
if(get_dir(loc, T) == dir)
|
|
return !density
|
|
else
|
|
return TRUE
|
|
|
|
/obj/machinery/door/firedoor/heavy
|
|
name = "heavy firelock"
|
|
icon = 'icons/obj/doors/Doorfire.dmi' //ICON OVERRIDEN IN SKYRAT AESTHETICS - SEE MODULE
|
|
glass = FALSE
|
|
explosion_block = 2
|
|
assemblytype = /obj/structure/firelock_frame/heavy
|
|
max_integrity = 550
|
|
|
|
|
|
/obj/item/electronics/firelock
|
|
name = "firelock circuitry"
|
|
desc = "A circuit board used in construction of firelocks."
|
|
icon_state = "mainboard"
|
|
|
|
/obj/structure/firelock_frame
|
|
name = "firelock frame"
|
|
desc = "A partially completed firelock."
|
|
icon = 'icons/obj/doors/Doorfire.dmi' //ICON OVERRIDEN IN SKYRAT AESTHETICS - SEE MODULE
|
|
icon_state = "frame1"
|
|
base_icon_state = "frame"
|
|
anchored = FALSE
|
|
density = TRUE
|
|
var/constructionStep = CONSTRUCTION_NO_CIRCUIT
|
|
var/reinforced = 0
|
|
|
|
/obj/structure/firelock_frame/examine(mob/user)
|
|
. = ..()
|
|
switch(constructionStep)
|
|
if(CONSTRUCTION_PANEL_OPEN)
|
|
. += span_notice("It is <i>unbolted</i> from the floor. The circuit could be removed with a <b>crowbar</b>.")
|
|
if(!reinforced)
|
|
. += span_notice("It could be reinforced with plasteel.")
|
|
if(CONSTRUCTION_NO_CIRCUIT)
|
|
. += span_notice("There are no <i>firelock electronics</i> in the frame. The frame could be <b>welded</b> apart .")
|
|
|
|
/obj/structure/firelock_frame/update_icon_state()
|
|
icon_state = "[base_icon_state][constructionStep]"
|
|
return ..()
|
|
|
|
/obj/structure/firelock_frame/attackby(obj/item/C, mob/user)
|
|
switch(constructionStep)
|
|
if(CONSTRUCTION_PANEL_OPEN)
|
|
if(C.tool_behaviour == TOOL_CROWBAR)
|
|
C.play_tool_sound(src)
|
|
user.visible_message(span_notice("[user] begins removing the circuit board from [src]..."), \
|
|
span_notice("You begin prying out the circuit board from [src]..."))
|
|
if(!C.use_tool(src, user, DEFAULT_STEP_TIME))
|
|
return
|
|
if(constructionStep != CONSTRUCTION_PANEL_OPEN)
|
|
return
|
|
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
|
user.visible_message(span_notice("[user] removes [src]'s circuit board."), \
|
|
span_notice("You remove the circuit board from [src]."))
|
|
new /obj/item/electronics/firelock(drop_location())
|
|
constructionStep = CONSTRUCTION_NO_CIRCUIT
|
|
update_appearance()
|
|
return
|
|
if(C.tool_behaviour == TOOL_WRENCH)
|
|
if(locate(/obj/machinery/door/firedoor) in get_turf(src))
|
|
to_chat(user, span_warning("There's already a firelock there."))
|
|
return
|
|
C.play_tool_sound(src)
|
|
user.visible_message(span_notice("[user] starts bolting down [src]..."), \
|
|
span_notice("You begin bolting [src]..."))
|
|
if(!C.use_tool(src, user, DEFAULT_STEP_TIME))
|
|
return
|
|
if(locate(/obj/machinery/door/firedoor) in get_turf(src))
|
|
return
|
|
user.visible_message(span_notice("[user] finishes the firelock."), \
|
|
span_notice("You finish the firelock."))
|
|
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
|
if(reinforced)
|
|
new /obj/machinery/door/firedoor/heavy(get_turf(src))
|
|
else
|
|
new /obj/machinery/door/firedoor(get_turf(src))
|
|
qdel(src)
|
|
return
|
|
if(istype(C, /obj/item/stack/sheet/plasteel))
|
|
var/obj/item/stack/sheet/plasteel/P = C
|
|
if(reinforced)
|
|
to_chat(user, span_warning("[src] is already reinforced."))
|
|
return
|
|
if(P.get_amount() < 2)
|
|
to_chat(user, span_warning("You need more plasteel to reinforce [src]."))
|
|
return
|
|
user.visible_message(span_notice("[user] begins reinforcing [src]..."), \
|
|
span_notice("You begin reinforcing [src]..."))
|
|
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
|
if(do_after(user, DEFAULT_STEP_TIME, target = src))
|
|
if(constructionStep != CONSTRUCTION_PANEL_OPEN || reinforced || P.get_amount() < 2 || !P)
|
|
return
|
|
user.visible_message(span_notice("[user] reinforces [src]."), \
|
|
span_notice("You reinforce [src]."))
|
|
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
|
P.use(2)
|
|
reinforced = 1
|
|
return
|
|
if(CONSTRUCTION_NO_CIRCUIT)
|
|
if(istype(C, /obj/item/electronics/firelock))
|
|
user.visible_message(span_notice("[user] starts adding [C] to [src]..."), \
|
|
span_notice("You begin adding a circuit board to [src]..."))
|
|
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
|
if(!do_after(user, DEFAULT_STEP_TIME, target = src))
|
|
return
|
|
if(constructionStep != CONSTRUCTION_NO_CIRCUIT)
|
|
return
|
|
qdel(C)
|
|
user.visible_message(span_notice("[user] adds a circuit to [src]."), \
|
|
span_notice("You insert and secure [C]."))
|
|
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, TRUE)
|
|
constructionStep = CONSTRUCTION_PANEL_OPEN
|
|
return
|
|
if(C.tool_behaviour == TOOL_WELDER)
|
|
if(!C.tool_start_check(user, amount=1))
|
|
return
|
|
user.visible_message(span_notice("[user] begins cutting apart [src]'s frame..."), \
|
|
span_notice("You begin slicing [src] apart..."))
|
|
|
|
if(C.use_tool(src, user, DEFAULT_STEP_TIME, volume=50, amount=1))
|
|
if(constructionStep != CONSTRUCTION_NO_CIRCUIT)
|
|
return
|
|
user.visible_message(span_notice("[user] cuts apart [src]!"), \
|
|
span_notice("You cut [src] into metal."))
|
|
var/turf/T = get_turf(src)
|
|
new /obj/item/stack/sheet/iron(T, 3)
|
|
if(reinforced)
|
|
new /obj/item/stack/sheet/plasteel(T, 2)
|
|
qdel(src)
|
|
return
|
|
if(istype(C, /obj/item/electroadaptive_pseudocircuit))
|
|
var/obj/item/electroadaptive_pseudocircuit/P = C
|
|
if(!P.adapt_circuit(user, DEFAULT_STEP_TIME * 0.5))
|
|
return
|
|
user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \
|
|
span_notice("You adapt a firelock circuit and slot it into the assembly."))
|
|
constructionStep = CONSTRUCTION_PANEL_OPEN
|
|
update_appearance()
|
|
return
|
|
return ..()
|
|
|
|
/obj/structure/firelock_frame/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
|
|
if(the_rcd.mode == RCD_DECONSTRUCT)
|
|
return list("mode" = RCD_DECONSTRUCT, "delay" = 50, "cost" = 16)
|
|
else if((constructionStep == CONSTRUCTION_NO_CIRCUIT) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS))
|
|
return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1)
|
|
return FALSE
|
|
|
|
/obj/structure/firelock_frame/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode)
|
|
switch(passed_mode)
|
|
if(RCD_UPGRADE_SIMPLE_CIRCUITS)
|
|
user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \
|
|
span_notice("You adapt a firelock circuit and slot it into the assembly."))
|
|
constructionStep = CONSTRUCTION_PANEL_OPEN
|
|
update_appearance()
|
|
return TRUE
|
|
if(RCD_DECONSTRUCT)
|
|
to_chat(user, span_notice("You deconstruct [src]."))
|
|
qdel(src)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/obj/structure/firelock_frame/heavy
|
|
name = "heavy firelock frame"
|
|
reinforced = TRUE
|
|
|
|
#undef CONSTRUCTION_PANEL_OPEN
|
|
#undef CONSTRUCTION_NO_CIRCUIT
|