/obj/machinery/door name = "door" desc = "It opens and closes." icon = 'icons/obj/doors/Doorint.dmi' icon_state = "door1" anchored = TRUE opacity = 1 density = TRUE layer = OPEN_DOOR_LAYER power_channel = ENVIRON max_integrity = 350 armor = list(melee = 30, bullet = 30, laser = 20, energy = 20, bomb = 10, bio = 100, rad = 100, fire = 80, acid = 70) CanAtmosPass = ATMOS_PASS_DENSITY flags_1 = PREVENT_CLICK_UNDER_1 var/secondsElectrified = 0 var/shockedby = list() var/visible = TRUE var/operating = FALSE var/glass = FALSE var/welded = FALSE var/normalspeed = 1 var/heat_proof = FALSE // For rglass-windowed airlocks and firedoors var/emergency = FALSE // Emergency access override var/sub_door = FALSE // true if it's meant to go under another door. var/closingLayer = CLOSED_DOOR_LAYER var/autoclose = FALSE //does it automatically close after some time var/safe = TRUE //whether the door detects things and mobs in its way and reopen or crushes them. var/locked = FALSE //whether the door is bolted or not. var/assemblytype //the type of door frame to drop during deconstruction var/auto_close //TO BE REMOVED, no longer used, it's just preventing a runtime with a map var edit. var/datum/effect_system/spark_spread/spark_system var/damage_deflection = 10 var/real_explosion_block //ignore this, just use explosion_block /obj/machinery/door/examine(mob/user) ..() to_chat(user, "Its maintenance panel is screwed in place.") /obj/machinery/door/New() ..() if(density) layer = CLOSED_DOOR_LAYER //Above most items if closed else layer = OPEN_DOOR_LAYER //Under all objects if opened. 2.7 due to tables being at 2.6 update_freelook_sight() air_update_turf(1) GLOB.airlocks += src spark_system = new /datum/effect_system/spark_spread spark_system.set_up(2, 1, src) //doors only block while dense though so we have to use the proc real_explosion_block = explosion_block explosion_block = EXPLOSION_BLOCK_PROC /obj/machinery/door/Destroy() density = FALSE air_update_turf(1) update_freelook_sight() GLOB.airlocks -= src if(spark_system) qdel(spark_system) spark_system = null return ..() //process() //return /obj/machinery/door/CollidedWith(atom/movable/AM) if(operating || emagged) return if(ismob(AM)) var/mob/B = AM if((isdrone(B) || iscyborg(B)) && B.stat) return if(isliving(AM)) var/mob/living/M = AM if(world.time - M.last_bumped <= 10) return //Can bump-open one airlock per second. This is to prevent shock spam. M.last_bumped = world.time if(M.restrained() && !check_access(null)) return bumpopen(M) return if(ismecha(AM)) var/obj/mecha/mecha = AM if(density) if(mecha.occupant) if(world.time - mecha.occupant.last_bumped <= 10) return mecha.occupant.last_bumped = world.time if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access))) open() else do_animate("deny") return return /obj/machinery/door/Move() var/turf/T = loc ..() move_update_air(T) /obj/machinery/door/CanPass(atom/movable/mover, turf/target) if(istype(mover) && mover.checkpass(PASSGLASS)) return !opacity return !density /obj/machinery/door/proc/bumpopen(mob/user) if(operating) return src.add_fingerprint(user) if(!src.requiresID()) user = null if(density && !emagged) if(allowed(user)) open() else do_animate("deny") return /obj/machinery/door/attack_ai(mob/user) return src.attack_hand(user) /obj/machinery/door/attack_hand(mob/user) return try_to_activate_door(user) /obj/machinery/door/attack_tk(mob/user) if(requiresID() && !allowed(null)) return ..() /obj/machinery/door/proc/try_to_activate_door(mob/user) add_fingerprint(user) if(operating || emagged) return if(!requiresID()) user = null //so allowed(user) always succeeds if(allowed(user)) if(density) open() else close() return if(density) do_animate("deny") /obj/machinery/door/allowed(mob/M) if(emergency) return TRUE return ..() /obj/machinery/door/proc/try_to_weld(obj/item/weldingtool/W, mob/user) return /obj/machinery/door/proc/try_to_crowbar(obj/item/I, mob/user) return /obj/machinery/door/attackby(obj/item/I, mob/user, params) if(user.a_intent != INTENT_HARM && (istype(I, /obj/item/crowbar) || istype(I, /obj/item/twohanded/fireaxe))) try_to_crowbar(I, user) return 1 else if(istype(I, /obj/item/weldingtool)) try_to_weld(I, user) return 1 else if(!(I.flags_1 & NOBLUDGEON_1) && user.a_intent != INTENT_HARM) try_to_activate_door(user) return 1 return ..() /obj/machinery/door/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) if(damage_flag == "melee" && damage_amount < damage_deflection) return 0 . = ..() /obj/machinery/door/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) . = ..() if(. && obj_integrity > 0) if(damage_amount >= 10 && prob(30)) spark_system.start() /obj/machinery/door/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) if(BRUTE) if(glass) playsound(loc, 'sound/effects/glasshit.ogg', 90, 1) else if(damage_amount) playsound(loc, 'sound/weapons/smash.ogg', 50, 1) else playsound(src, 'sound/weapons/tap.ogg', 50, 1) if(BURN) playsound(src.loc, 'sound/items/welder.ogg', 100, 1) /obj/machinery/door/emp_act(severity) if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) ) INVOKE_ASYNC(src, .proc/open) if(prob(40/severity)) if(secondsElectrified == 0) secondsElectrified = -1 shockedby += "\[[time_stamp()]\]EM Pulse" addtimer(CALLBACK(src, .proc/unelectrify), 300) ..() /obj/machinery/door/proc/unelectrify() secondsElectrified = 0 /obj/machinery/door/update_icon() if(density) icon_state = "door1" else icon_state = "door0" /obj/machinery/door/proc/do_animate(animation) switch(animation) if("opening") if(panel_open) flick("o_doorc0", src) else flick("doorc0", src) if("closing") if(panel_open) flick("o_doorc1", src) else flick("doorc1", src) if("deny") if(!stat) flick("door_deny", src) /obj/machinery/door/proc/open() if(!density) return 1 if(operating) return operating = TRUE do_animate("opening") set_opacity(0) sleep(5) density = FALSE sleep(5) layer = OPEN_DOOR_LAYER update_icon() set_opacity(0) operating = FALSE air_update_turf(1) update_freelook_sight() if(autoclose) spawn(autoclose) close() return 1 /obj/machinery/door/proc/close() if(density) return 1 if(operating) return if(safe) for(var/atom/movable/M in get_turf(src)) if(M.density && M != src) //something is blocking the door if(autoclose) addtimer(CALLBACK(src, .proc/autoclose), 60) return operating = TRUE do_animate("closing") layer = closingLayer sleep(5) density = TRUE sleep(5) update_icon() if(visible && !glass) set_opacity(1) operating = FALSE air_update_turf(1) update_freelook_sight() if(safe) CheckForMobs() else crush() return 1 /obj/machinery/door/proc/CheckForMobs() if(locate(/mob/living) in get_turf(src)) sleep(1) open() /obj/machinery/door/proc/crush() for(var/mob/living/L in get_turf(src)) L.visible_message("[src] closes on [L], crushing them!", "[src] closes on you and crushes you!") if(isalien(L)) //For xenos L.adjustBruteLoss(DOOR_CRUSH_DAMAGE * 1.5) //Xenos go into crit after aproximately the same amount of crushes as humans. L.emote("roar") else if(ishuman(L)) //For humans L.adjustBruteLoss(DOOR_CRUSH_DAMAGE) L.emote("scream") L.Knockdown(100) else if(ismonkey(L)) //For monkeys L.adjustBruteLoss(DOOR_CRUSH_DAMAGE) L.Knockdown(100) else //for simple_animals & borgs L.adjustBruteLoss(DOOR_CRUSH_DAMAGE) var/turf/location = get_turf(src) //add_blood doesn't work for borgs/xenos, but add_blood_floor does. L.add_splatter_floor(location) for(var/obj/mecha/M in get_turf(src)) M.take_damage(DOOR_CRUSH_DAMAGE) /obj/machinery/door/proc/autoclose() if(!QDELETED(src) && !density && !operating && !locked && !welded && autoclose) close() /obj/machinery/door/proc/requiresID() return 1 /obj/machinery/door/proc/hasPower() return !(stat & NOPOWER) /obj/machinery/door/proc/update_freelook_sight() if(!glass && GLOB.cameranet) GLOB.cameranet.updateVisibility(src, 0) /obj/machinery/door/BlockSuperconductivity() // All non-glass airlocks block heat, this is intended. if(opacity || heat_proof) return 1 return 0 /obj/machinery/door/morgue icon = 'icons/obj/doors/doormorgue.dmi' /obj/machinery/door/get_dumping_location(obj/item/storage/source,mob/user) return null /obj/machinery/door/proc/lock() return /obj/machinery/door/proc/unlock() return /obj/machinery/door/proc/hostile_lockdown(mob/origin) if(!stat) //So that only powered doors are closed. close() //Close ALL the doors! /obj/machinery/door/proc/disable_lockdown() if(!stat) //Opens only powered doors. open() //Open everything! /obj/machinery/door/ex_act(severity, target) //if it blows up a wall it should blow up a door ..(severity ? max(1, severity - 1) : 0, target) /obj/machinery/door/GetExplosionBlock() return density ? real_explosion_block : 0