mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
303 lines
11 KiB
Plaintext
303 lines
11 KiB
Plaintext
// BLAST DOORS
|
|
//
|
|
// Refactored 27.12.2014 by Atlantis
|
|
//
|
|
// Blast doors are suposed to be reinforced versions of regular doors. Instead of being manually
|
|
// controlled they use buttons or other means of remote control. This is why they cannot be emagged
|
|
// as they lack any ID scanning system, they just handle remote control signals. Subtypes have
|
|
// different icons, which are defined by set of variables. Subtypes are on bottom of this file.
|
|
|
|
// UPDATE 06.04.2018
|
|
// The emag thing wasn't working as intended, manually overwrote it.
|
|
|
|
/obj/machinery/door/blast
|
|
name = "Blast Door"
|
|
desc = "That looks like it doesn't open easily."
|
|
icon = 'icons/obj/doors/rapid_pdoor.dmi'
|
|
icon_state = null
|
|
min_force = 20 //minimum amount of force needed to damage the door with a melee weapon
|
|
var/material/implicit_material
|
|
// Icon states for different shutter types. Simply change this instead of rewriting the update_icon proc.
|
|
var/icon_state_open = null
|
|
var/icon_state_opening = null
|
|
var/icon_state_closed = null
|
|
var/icon_state_closing = null
|
|
var/open_sound = 'sound/machines/blastdooropen.ogg'
|
|
var/close_sound = 'sound/machines/blastdoorclose.ogg'
|
|
|
|
closed_layer = ON_WINDOW_LAYER // Above airlocks when closed
|
|
var/id = 1.0
|
|
dir = 1
|
|
explosion_resistance = 25
|
|
|
|
//Most blast doors are infrequently toggled and sometimes used with regular doors anyways,
|
|
//turning this off prevents awkward zone geometry in places like medbay lobby, for example.
|
|
block_air_zones = 0
|
|
|
|
/obj/machinery/door/blast/Initialize()
|
|
. = ..()
|
|
implicit_material = get_material_by_name("plasteel")
|
|
|
|
/obj/machinery/door/blast/get_material()
|
|
return implicit_material
|
|
|
|
// Proc: Bumped()
|
|
// Parameters: 1 (AM - Atom that tried to walk through this object)
|
|
// Description: If we are open returns zero, otherwise returns result of parent function.
|
|
/obj/machinery/door/blast/Bumped(atom/AM)
|
|
if(!density)
|
|
return ..()
|
|
else
|
|
return 0
|
|
|
|
// Proc: update_icon()
|
|
// Parameters: None
|
|
// Description: Updates icon of this object. Uses icon state variables.
|
|
/obj/machinery/door/blast/update_icon()
|
|
if(density)
|
|
icon_state = icon_state_closed
|
|
else
|
|
icon_state = icon_state_open
|
|
SSradiation.resistance_cache.Remove(get_turf(src))
|
|
return
|
|
|
|
// Has to be in here, comment at the top is older than the emag_act code on doors proper
|
|
/obj/machinery/door/blast/emag_act()
|
|
return -1
|
|
|
|
// Blast doors are triggered remotely, so nobody is allowed to physically influence it.
|
|
/obj/machinery/door/blast/allowed(mob/M)
|
|
return FALSE
|
|
|
|
// Proc: force_open()
|
|
// Parameters: None
|
|
// Description: Opens the door. No checks are done inside this proc.
|
|
/obj/machinery/door/blast/proc/force_open()
|
|
src.operating = 1
|
|
playsound(src, open_sound, 100, 1)
|
|
flick(icon_state_opening, src)
|
|
src.density = 0
|
|
update_nearby_tiles()
|
|
src.update_icon()
|
|
src.set_opacity(0)
|
|
sleep(15)
|
|
src.layer = open_layer
|
|
src.operating = 0
|
|
|
|
// Proc: force_close()
|
|
// Parameters: None
|
|
// Description: Closes the door. No checks are done inside this proc.
|
|
/obj/machinery/door/blast/proc/force_close()
|
|
src.operating = 1
|
|
playsound(src, close_sound, 100, 1)
|
|
src.layer = closed_layer
|
|
flick(icon_state_closing, src)
|
|
src.density = 1
|
|
update_nearby_tiles()
|
|
src.update_icon()
|
|
src.set_opacity(1)
|
|
sleep(15)
|
|
src.operating = 0
|
|
|
|
// Proc: force_toggle()
|
|
// Parameters: None
|
|
// Description: Opens or closes the door, depending on current state. No checks are done inside this proc.
|
|
/obj/machinery/door/blast/proc/force_toggle(var/forced = 0, mob/user as mob)
|
|
if (forced)
|
|
playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1)
|
|
|
|
if(src.density)
|
|
src.force_open()
|
|
else
|
|
src.force_close()
|
|
|
|
//Proc: attack_hand
|
|
//Description: Attacked with empty hand. Only to allow special attack_bys.
|
|
/obj/machinery/door/blast/attack_hand(mob/user as mob)
|
|
if(istype(user, /mob/living/carbon/human))
|
|
var/mob/living/carbon/human/X = user
|
|
if(istype(X.species, /datum/species/xenos))
|
|
src.attack_alien(user)
|
|
return
|
|
..()
|
|
|
|
|
|
// Proc: attackby()
|
|
// Parameters: 2 (C - Item this object was clicked with, user - Mob which clicked this object)
|
|
// Description: If we are clicked with crowbar, wielded fire axe, or armblade, try to manually open the door.
|
|
// This only works on broken doors or doors without power. Also allows repair with Plasteel.
|
|
/obj/machinery/door/blast/attackby(obj/item/weapon/C as obj, mob/user as mob)
|
|
src.add_fingerprint(user)
|
|
if(istype(C, /obj/item/weapon)) // For reasons unknown, sometimes C is actually not what it is advertised as, like a mob.
|
|
if(C.pry == 1 && (user.a_intent != I_HURT || (stat & BROKEN))) // Can we pry it open with something, like a crowbar/fireaxe/lingblade?
|
|
if(istype(C,/obj/item/weapon/material/twohanded/fireaxe)) // Fireaxes need to be in both hands to pry.
|
|
var/obj/item/weapon/material/twohanded/fireaxe/F = C
|
|
if(!F.wielded)
|
|
to_chat(user, "<span class='warning'>You need to be wielding \the [F] to do that.</span>")
|
|
return
|
|
|
|
// If we're at this point, it's a fireaxe in both hands or something else that doesn't care for twohanding.
|
|
if(((stat & NOPOWER) || (stat & BROKEN)) && !( src.operating ))
|
|
force_toggle(1, user)
|
|
|
|
else
|
|
to_chat(user, "<span class='notice'>[src]'s motors resist your effort.</span>")
|
|
return
|
|
|
|
|
|
else if(src.density && (user.a_intent == I_HURT)) //If we can't pry it open and it's a weapon, let's hit it.
|
|
var/obj/item/weapon/W = C
|
|
user.setClickCooldown(user.get_attack_speed(W))
|
|
if(W.damtype == BRUTE || W.damtype == BURN)
|
|
user.do_attack_animation(src)
|
|
if(W.force < min_force)
|
|
user.visible_message("<span class='danger'>\The [user] hits \the [src] with \the [W] with no visible effect.</span>")
|
|
else
|
|
user.visible_message("<span class='danger'>\The [user] forcefully strikes \the [src] with \the [W]!</span>")
|
|
playsound(src, hitsound, 100, 1)
|
|
take_damage(W.force*0.35) //it's a blast door, it should take a while. -Luke
|
|
return
|
|
|
|
else if(istype(C, /obj/item/stack/material) && C.get_material_name() == "plasteel") // Repairing.
|
|
var/amt = CEILING((maxhealth - health)/150, 1)
|
|
if(!amt)
|
|
to_chat(user, "<span class='notice'>\The [src] is already fully repaired.</span>")
|
|
return
|
|
var/obj/item/stack/P = C
|
|
if(P.amount < amt)
|
|
to_chat(user, "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>")
|
|
return
|
|
to_chat(user, "<span class='notice'>You begin repairing [src]...</span>")
|
|
if(do_after(usr, 30))
|
|
if(P.use(amt))
|
|
to_chat(user, "<span class='notice'>You have repaired \The [src]</span>")
|
|
src.repair()
|
|
else
|
|
to_chat(user, "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>")
|
|
|
|
else if(src.density && (user.a_intent == I_HURT)) //If we can't pry it open and it's not a weapon.... Eh, let's attack it anyway.
|
|
var/obj/item/weapon/W = C
|
|
user.setClickCooldown(user.get_attack_speed(W))
|
|
if(W.damtype == BRUTE || W.damtype == BURN)
|
|
user.do_attack_animation(src)
|
|
if(W.force < min_force) //No actual non-weapon item shouls have a force greater than the min_force, but let's include this just in case.
|
|
user.visible_message("<span class='danger'>\The [user] hits \the [src] with \the [W] with no visible effect.</span>")
|
|
else
|
|
user.visible_message("<span class='danger'>\The [user] forcefully strikes \the [src] with \the [W]!</span>")
|
|
playsound(src, hitsound, 100, 1)
|
|
take_damage(W.force*0.15) //If the item isn't a weapon, let's make this take longer than usual to break it down.
|
|
return
|
|
|
|
// Proc: attack_alien()
|
|
// Parameters: Attacking Xeno mob.
|
|
// Description: Forces open the door after a delay.
|
|
/obj/machinery/door/blast/attack_alien(var/mob/user) //Familiar, right? Doors.
|
|
if(istype(user, /mob/living/carbon/human))
|
|
var/mob/living/carbon/human/X = user
|
|
if(istype(X.species, /datum/species/xenos))
|
|
if(src.density)
|
|
visible_message("<span class='alium'>\The [user] begins forcing \the [src] open!</span>")
|
|
if(do_after(user, 15 SECONDS,src))
|
|
playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1)
|
|
visible_message("<span class='danger'>\The [user] forces \the [src] open!</span>")
|
|
force_open(1)
|
|
else
|
|
visible_message("<span class='alium'>\The [user] begins forcing \the [src] closed!</span>")
|
|
if(do_after(user, 5 SECONDS,src))
|
|
playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1)
|
|
visible_message("<span class='danger'>\The [user] forces \the [src] closed!</span>")
|
|
force_close(1)
|
|
else
|
|
visible_message("<span class='notice'>\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].</span>")
|
|
return
|
|
..()
|
|
|
|
// Proc: attack_generic()
|
|
// Parameters: Attacking simple mob, incoming damage.
|
|
// Description: Checks the power or integrity of the blast door, if either have failed, chekcs the damage to determine if the creature would be able to open the door by force. Otherwise, super.
|
|
/obj/machinery/door/blast/attack_generic(mob/living/user, damage)
|
|
if(stat & (BROKEN|NOPOWER))
|
|
if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD)
|
|
user.set_AI_busy(TRUE) // If the mob doesn't have an AI attached, this won't do anything.
|
|
if(src.density)
|
|
visible_message("<span class='danger'>\The [user] starts forcing \the [src] open!</span>")
|
|
if(do_after(user, 5 SECONDS, src))
|
|
visible_message("<span class='danger'>\The [user] forces \the [src] open!</span>")
|
|
force_open(1)
|
|
else
|
|
visible_message("<span class='danger'>\The [user] starts forcing \the [src] closed!</span>")
|
|
if(do_after(user, 2 SECONDS, src))
|
|
visible_message("<span class='danger'>\The [user] forces \the [src] closed!</span>")
|
|
force_close(1)
|
|
user.set_AI_busy(FALSE)
|
|
else
|
|
visible_message("<span class='notice'>\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].</span>")
|
|
return
|
|
..()
|
|
|
|
// Proc: open()
|
|
// Parameters: None
|
|
// Description: Opens the door. Does necessary checks. Automatically closes if autoclose is true
|
|
/obj/machinery/door/blast/open(var/forced = 0)
|
|
if(forced)
|
|
force_open()
|
|
return 1
|
|
else
|
|
if (src.operating || (stat & BROKEN || stat & NOPOWER))
|
|
return 1
|
|
force_open()
|
|
|
|
if(autoclose && src.operating && !(stat & BROKEN || stat & NOPOWER))
|
|
addtimer(CALLBACK(src, .proc/close, 15 SECONDS))
|
|
return 1
|
|
|
|
// Proc: close()
|
|
// Parameters: None
|
|
// Description: Closes the door. Does necessary checks.
|
|
/obj/machinery/door/blast/close()
|
|
if (src.operating || (stat & BROKEN || stat & NOPOWER))
|
|
return
|
|
force_close()
|
|
|
|
|
|
// Proc: repair()
|
|
// Parameters: None
|
|
// Description: Fully repairs the blast door.
|
|
/obj/machinery/door/blast/proc/repair()
|
|
health = maxhealth
|
|
if(stat & BROKEN)
|
|
stat &= ~BROKEN
|
|
|
|
/*
|
|
// This replicates the old functionality coded into CanPass() for this object, however it appeared to have made blast doors not airtight.
|
|
// If for some reason this is actually needed for something important, uncomment this.
|
|
/obj/machinery/door/blast/CanZASPass(turf/T, is_zone)
|
|
if(is_zone)
|
|
return TRUE
|
|
return ..()
|
|
*/
|
|
|
|
// SUBTYPE: Regular
|
|
// Your classical blast door, found almost everywhere.
|
|
obj/machinery/door/blast/regular
|
|
icon_state_open = "pdoor0"
|
|
icon_state_opening = "pdoorc0"
|
|
icon_state_closed = "pdoor1"
|
|
icon_state_closing = "pdoorc1"
|
|
icon_state = "pdoor1"
|
|
maxhealth = 600
|
|
|
|
obj/machinery/door/blast/regular/open
|
|
icon_state = "pdoor0"
|
|
density = 0
|
|
opacity = 0
|
|
|
|
// SUBTYPE: Shutters
|
|
// Nicer looking, and also weaker, shutters. Found in kitchen and similar areas.
|
|
/obj/machinery/door/blast/shutters
|
|
icon_state_open = "shutter0"
|
|
icon_state_opening = "shutterc0"
|
|
icon_state_closed = "shutter1"
|
|
icon_state_closing = "shutterc1"
|
|
icon_state = "shutter1"
|