/obj/structure/plasticflaps name = "airtight plastic flaps" desc = "Heavy duty, airtight, plastic flaps. Definitely can't get past those. No way." gender = PLURAL icon = 'icons/obj/structures.dmi' icon_state = "plasticflaps" armor_type = /datum/armor/structure_plasticflaps density = FALSE anchored = TRUE can_atmos_pass = ATMOS_PASS_NO can_astar_pass = CANASTARPASS_ALWAYS_PROC integrity_failure = 0.75 // This layer only matters for determining when you click it vs other objects layer = BELOW_OPEN_DOOR_LAYER /// If TRUE, we can't pass through unless the mob is resting (or fulfills more specific requirements) var/require_resting = TRUE /// Layer the flaps render on var/flaps_layer = ABOVE_MOB_LAYER /// Alpha of the flaps var/flaps_alpha = 255 /// Limits how much damage from environmental fire we can take per second COOLDOWN_DECLARE(burn_damage_cd) /datum/armor/structure_plasticflaps melee = 100 bullet = 80 laser = 80 energy = 100 bomb = 50 fire = 50 acid = 50 /obj/structure/plasticflaps/opaque opacity = TRUE /obj/structure/plasticflaps/kitchen name = "cold room plastic flaps" desc = "Light and airtight plastic flaps made to keep the cold room cold and the warm room warm." armor_type = /datum/armor/structure_plasticflaps/kitchen require_resting = FALSE flaps_alpha = 150 /datum/armor/structure_plasticflaps/kitchen melee = 50 fire = 20 acid = 20 /obj/structure/plasticflaps/Initialize(mapload) . = ..() alpha = 0 gen_overlay() air_update_turf(TRUE, TRUE) var/static/list/loc_connections = list( COMSIG_ATOM_EXITED = PROC_REF(play_plastic_sound), ) AddElement(/datum/element/connect_loc, loc_connections) var/static/list/adjacent_loc_connections = list( COMSIG_TURF_EXPOSE = PROC_REF(check_melt), ) AddComponent(/datum/component/connect_range, tracked = src, connections = adjacent_loc_connections, range = 1, works_in_containers = FALSE) /obj/structure/plasticflaps/proc/play_plastic_sound(obj/source, atom/movable/exiting) SIGNAL_HANDLER if(isitem(exiting)) var/obj/item/item_exiter = exiting if(item_exiter.w_class <= WEIGHT_CLASS_NORMAL) return if(item_exiter.item_flags & ABSTRACT) return if(isliving(exiting)) var/mob/living/living_exiter = exiting if(living_exiter.mob_size <= MOB_SIZE_TINY) return // you're crawling under them if(living_exiter.body_position == LYING_DOWN) return if(living_exiter.incorporeal_move) return if(HAS_TRAIT(exiting, TRAIT_MAGICALLY_PHASED)) return if(locate(/obj/structure/plasticflaps) in exiting.loc) return playsound(src, 'sound/effects/plasticflaps.ogg', 50, TRUE, ignore_walls = FALSE, falloff_exponent = 8, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) /obj/structure/plasticflaps/proc/check_melt(turf/source, datum/gas_mixture/air, temperature) SIGNAL_HANDLER if(temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) return if(!COOLDOWN_FINISHED(src, burn_damage_cd)) return COOLDOWN_START(src, burn_damage_cd, 1 SECONDS) var/percent_damage_taken = clamp(0.2 * (temperature / (FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 2.5)), 0.05, 0.25) take_damage(max_integrity * percent_damage_taken, BURN, FIRE, sound_effect = FALSE) /obj/structure/plasticflaps/atom_break(damage_flag) if(damage_flag == FIRE) visible_message(span_warning("[src] start\s to melt from the heat!")) return ..() /obj/structure/plasticflaps/atom_destruction(damage_flag) if(damage_flag == FIRE) visible_message(span_warning("[src] melt\s away into plastic goo!")) return ..() /obj/structure/plasticflaps/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) if(!same_z_layer) SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) gen_overlay() return ..() /obj/structure/plasticflaps/setDir(newdir) . = ..() SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) gen_overlay() /obj/structure/plasticflaps/proc/gen_overlay() var/turf/our_turf = get_turf(src) //you see mobs under it, but you hit them like they are above it SSvis_overlays.add_vis_overlay(src, icon, icon_state, layer = flaps_layer, plane = MUTATE_PLANE(GAME_PLANE, our_turf), dir = dir, alpha = flaps_alpha, add_appearance_flags = RESET_ALPHA, ) /obj/structure/plasticflaps/vv_edit_var(var_name, var_val) . = ..() var/list/relevant_vars = list( NAMEOF(src, flaps_layer), NAMEOF(src, flaps_alpha), NAMEOF(src, dir), NAMEOF(src, icon), NAMEOF(src, icon_state), ) if(var_name in relevant_vars) SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) gen_overlay() /obj/structure/plasticflaps/examine(mob/user) . = ..() if(anchored) . += span_notice("[src] are screwed to the floor.") else . += span_notice("[src] are no longer screwed to the floor, and the flaps can be cut apart.") /obj/structure/plasticflaps/screwdriver_act(mob/living/user, obj/item/W) if(..()) return TRUE add_fingerprint(user) var/action = anchored ? "unscrews [src] from" : "screws [src] to" var/uraction = anchored ? "unscrew [src] from" : "screw [src] to" user.visible_message(span_warning("[user] [action] the floor."), span_notice("You start to [uraction] the floor..."), span_hear("You hear rustling noises.")) if(!W.use_tool(src, user, 100, volume=100, extra_checks = CALLBACK(src, PROC_REF(check_anchored_state), anchored))) return TRUE set_anchored(!anchored) update_atmos_behaviour() air_update_turf(TRUE) to_chat(user, span_notice("You [uraction] the floor.")) return TRUE ///Update the flaps behaviour to gases, if not anchored will let air pass through /obj/structure/plasticflaps/proc/update_atmos_behaviour() can_atmos_pass = anchored ? ATMOS_PASS_NO : ATMOS_PASS_YES /obj/structure/plasticflaps/wirecutter_act(mob/living/user, obj/item/W) . = ..() if(!anchored) user.visible_message(span_warning("[user] cuts apart [src]."), span_notice("You start to cut apart [src]."), span_hear("You hear cutting.")) if(W.use_tool(src, user, 50, volume=100)) if(anchored) return TRUE to_chat(user, span_notice("You cut apart [src].")) var/obj/item/stack/sheet/plastic/five/P = new(loc) if (!QDELETED(P)) P.add_fingerprint(user) qdel(src) return TRUE /obj/structure/plasticflaps/proc/check_anchored_state(check_anchored) if(anchored != check_anchored) return FALSE return TRUE /obj/structure/plasticflaps/CanAStarPass(to_dir, datum/can_pass_info/pass_info) if(!require_resting) return TRUE if(pass_info.is_living) if(pass_info.is_bot) return TRUE if(pass_info.can_ventcrawl && pass_info.mob_size != MOB_SIZE_TINY) return FALSE if(pass_info.pass_flags & PASSFLAPS) return TRUE if(pass_info.pulling_info) return CanAStarPass(to_dir, pass_info.pulling_info) return TRUE //diseases, stings, etc can pass /obj/structure/plasticflaps/CanAllowThrough(atom/movable/mover, border_dir) . = ..() if(mover.pass_flags & PASSFLAPS) //For anything specifically engineered to cross plastic flaps. return TRUE if((mover.pass_flags & PASSGLASS) && prob(60)) return TRUE if(!require_resting) return TRUE if(istype(mover, /obj/structure/bed)) var/obj/structure/bed/bed_mover = mover if(bed_mover.density || bed_mover.has_buckled_mobs())//if it's a bed/chair and is dense or someone is buckled, it will not pass return FALSE else if(istype(mover, /obj/structure/closet/cardboard)) var/obj/structure/closet/cardboard/cardboard_mover = mover if(cardboard_mover.move_delay) return FALSE else if(ismecha(mover)) return FALSE else if(isliving(mover)) // You Shall Not Pass! var/mob/living/living_mover = mover if(istype(living_mover.buckled, /mob/living/simple_animal/bot/mulebot)) // mulebot passenger gets a free pass. return TRUE if(living_mover.body_position == STANDING_UP && living_mover.mob_size != MOB_SIZE_TINY && !(HAS_TRAIT(living_mover, TRAIT_VENTCRAWLER_ALWAYS) || HAS_TRAIT(living_mover, TRAIT_VENTCRAWLER_NUDE))) return FALSE //If you're not laying down, or a small creature, or a ventcrawler, then no pass. return . /obj/structure/plasticflaps/atom_deconstruct(disassembled = TRUE) new /obj/item/stack/sheet/plastic/five(loc) /obj/structure/plasticflaps/Destroy() var/atom/oldloc = loc . = ..() if (oldloc) oldloc.air_update_turf(TRUE, FALSE)