Files
S.P.L.U.R.T-Station-13/code/game/machinery/shieldgen.dm

464 lines
14 KiB
Plaintext

/obj/structure/emergency_shield
name = "emergency energy shield"
desc = "An energy shield used to contain hull breaches."
icon = 'icons/effects/effects.dmi'
icon_state = "shield-old"
density = TRUE
move_resist = INFINITY
opacity = 0
anchored = TRUE
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
max_integrity = 200 //The shield can only take so much beating (prevents perma-prisons)
CanAtmosPass = ATMOS_PASS_DENSITY
/obj/structure/emergency_shield/Initialize(mapload)
. = ..()
setDir(pick(GLOB.cardinals))
air_update_turf(1)
/obj/structure/emergency_shield/Move()
var/turf/T = loc
. = ..()
move_update_air(T)
/obj/structure/emergency_shield/emp_act(severity)
. = ..()
if (. & EMP_PROTECT_SELF)
return
if(severity >= 70)
qdel(src)
else
take_damage(severity/1.3, BRUTE, ENERGY, 0)
/obj/structure/emergency_shield/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BURN)
playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
if(BRUTE)
playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
/obj/structure/emergency_shield/take_damage(damage, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
if(.) //damage was dealt
new /obj/effect/temp_visual/impact_effect/ion(loc)
/obj/structure/emergency_shield/sanguine
name = "sanguine barrier"
desc = "A potent shield summoned by cultists to defend their rites."
icon_state = "shield-red"
max_integrity = 60
/obj/structure/emergency_shield/sanguine/emp_act(severity)
return
/obj/structure/emergency_shield/invoker
name = "Invoker's Shield"
desc = "A weak shield summoned by cultists to protect them while they carry out delicate rituals."
color = "#FF0000"
max_integrity = 20
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = ABOVE_MOB_LAYER
/obj/structure/emergency_shield/invoker/emp_act(severity)
return
/obj/machinery/shieldgen
name = "anti-breach shielding projector"
desc = "Used to seal minor hull breaches."
icon = 'icons/obj/objects.dmi'
icon_state = "shieldoff"
density = TRUE
opacity = 0
anchored = FALSE
pressure_resistance = 2*ONE_ATMOSPHERE
req_access = list(ACCESS_ENGINE)
max_integrity = 100
var/active = FALSE
var/list/deployed_shields
var/locked = FALSE
var/shield_range = 4
/obj/machinery/shieldgen/Initialize(mapload)
. = ..()
deployed_shields = list()
if(mapload && active && anchored)
shields_up()
/obj/machinery/shieldgen/Destroy()
QDEL_LIST(deployed_shields)
return ..()
/obj/machinery/shieldgen/proc/shields_up()
active = TRUE
update_icon()
move_resist = INFINITY
for(var/turf/target_tile in range(shield_range, src))
if(isspaceturf(target_tile) && !(locate(/obj/structure/emergency_shield) in target_tile))
if(!(stat & BROKEN) || prob(33))
deployed_shields += new /obj/structure/emergency_shield(target_tile)
/obj/machinery/shieldgen/proc/shields_down()
active = FALSE
move_resist = initial(move_resist)
update_icon()
QDEL_LIST(deployed_shields)
/obj/machinery/shieldgen/process()
if((stat & BROKEN) && active)
if(deployed_shields.len && prob(5))
qdel(pick(deployed_shields))
/obj/machinery/shieldgen/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(!(stat && BROKEN))
stat |= BROKEN
locked = pick(0,1)
update_icon()
/obj/machinery/shieldgen/interact(mob/user)
. = ..()
if(.)
return
if(locked && !hasSiliconAccessInArea(user))
to_chat(user, "<span class='warning'>The machine is locked, you are unable to use it!</span>")
return
if(panel_open)
to_chat(user, "<span class='warning'>The panel must be closed before operating this machine!</span>")
return
if (active)
user.visible_message("[user] deactivated \the [src].", \
"<span class='notice'>You deactivate \the [src].</span>", \
"<span class='italics'>You hear heavy droning fade out.</span>")
shields_down()
else
if(anchored)
user.visible_message("[user] activated \the [src].", \
"<span class='notice'>You activate \the [src].</span>", \
"<span class='italics'>You hear heavy droning.</span>")
shields_up()
else
to_chat(user, "<span class='warning'>The device must first be secured to the floor!</span>")
return
/obj/machinery/shieldgen/attackby(obj/item/W, mob/user, params)
if(W.tool_behaviour == TOOL_SCREWDRIVER)
W.play_tool_sound(src, 100)
panel_open = !panel_open
if(panel_open)
to_chat(user, "<span class='notice'>You open the panel and expose the wiring.</span>")
else
to_chat(user, "<span class='notice'>You close the panel.</span>")
else if(istype(W, /obj/item/stack/cable_coil) && (stat & BROKEN) && panel_open)
var/obj/item/stack/cable_coil/coil = W
if (coil.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one length of cable to repair [src]!</span>")
return
to_chat(user, "<span class='notice'>You begin to replace the wires...</span>")
if(W.use_tool(src, user, 30, 1))
obj_integrity = max_integrity
stat &= ~BROKEN
to_chat(user, "<span class='notice'>You repair \the [src].</span>")
update_icon()
else if(W.tool_behaviour == TOOL_WRENCH)
if(locked)
to_chat(user, "<span class='warning'>The bolts are covered! Unlocking this would retract the covers.</span>")
return
if(!anchored && !isinspace())
W.play_tool_sound(src, 100)
to_chat(user, "<span class='notice'>You secure \the [src] to the floor!</span>")
setAnchored(TRUE)
else if(anchored)
W.play_tool_sound(src, 100)
to_chat(user, "<span class='notice'>You unsecure \the [src] from the floor!</span>")
if(active)
to_chat(user, "<span class='notice'>\The [src] shuts off!</span>")
shields_down()
setAnchored(FALSE)
else if(W.GetID())
if(allowed(user) && !(obj_flags & EMAGGED))
locked = !locked
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] the controls.</span>")
else if(obj_flags & EMAGGED)
to_chat(user, "<span class='danger'>Error, access controller damaged!</span>")
else
to_chat(user, "<span class='danger'>Access denied.</span>")
else
return ..()
/obj/machinery/shieldgen/emag_act(mob/user)
. = ..()
if(obj_flags & EMAGGED)
to_chat(user, "<span class='warning'>The access controller is damaged!</span>")
return
obj_flags |= EMAGGED
locked = FALSE
playsound(src, "sparks", 100, 1)
to_chat(user, "<span class='warning'>You short out the access controller.</span>")
return TRUE
/obj/machinery/shieldgen/update_icon_state()
if(active)
icon_state = (stat & BROKEN) ? "shieldonbr":"shieldon"
else
icon_state = (stat & BROKEN) ? "shieldoffbr":"shieldoff"
#define ACTIVE_SETUPFIELDS 1
#define ACTIVE_HASFIELDS 2
/obj/machinery/shieldwallgen
name = "shield wall generator"
desc = "A shield generator."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "Shield_Gen"
anchored = FALSE
density = TRUE
req_access = list(ACCESS_TELEPORTER)
flags_1 = CONDUCT_1
use_power = NO_POWER_USE
max_integrity = 300
var/active = FALSE
var/power = 0
var/maximum_stored_power = 500
var/locked = TRUE
var/shield_range = 8
var/obj/structure/cable/attached // the attached cable
/obj/machinery/shieldwallgen/xenobiologyaccess //use in xenobiology containment
name = "xenobiology shield wall generator"
desc = "A shield generator meant for use in xenobiology."
icon_state = "Shield_Gen"
req_access = list(ACCESS_XENOBIOLOGY)
/obj/machinery/shieldwallgen/Destroy()
for(var/d in GLOB.cardinals)
cleanup_field(d)
return ..()
/obj/machinery/shieldwallgen/proc/power()
if(!anchored)
power = 0
return
var/turf/T = get_turf(src)
var/obj/structure/cable/C = T.get_cable_node()
var/datum/powernet/PN
if(C)
PN = C.powernet //find the powernet of the connected cable
if(!PN)
return
var/surplus = max(PN.avail - PN.load, 0)
var/avail_power = min(rand(50,200), surplus)
if(avail_power)
power += avail_power
PN.load += avail_power //uses powernet power.
/obj/machinery/shieldwallgen/process()
power()
use_stored_power(50)
/obj/machinery/shieldwallgen/proc/use_stored_power(amount)
power = clamp(power - amount, 0, maximum_stored_power)
update_activity()
/obj/machinery/shieldwallgen/proc/update_activity()
if(active)
icon_state = "Shield_Gen +a"
if(active == ACTIVE_SETUPFIELDS)
var/fields = 0
for(var/d in GLOB.cardinals)
if(setup_field(d))
fields++
if(fields)
active = ACTIVE_HASFIELDS
if(!power)
visible_message("<span class='danger'>The [src.name] shuts down due to lack of power!</span>", \
"<span class='italics'>You hear heavy droning fade out.</span>")
icon_state = "Shield_Gen"
active = FALSE
for(var/d in GLOB.cardinals)
cleanup_field(d)
else
icon_state = "Shield_Gen"
for(var/d in GLOB.cardinals)
cleanup_field(d)
/obj/machinery/shieldwallgen/proc/setup_field(direction)
if(!direction)
return
var/turf/T = loc
var/obj/machinery/shieldwallgen/G
var/steps = 0
var/opposite_direction = turn(direction, 180)
for(var/i in 1 to shield_range) //checks out to 8 tiles away for another generator
T = get_step(T, direction)
G = (locate(/obj/machinery/shieldwallgen) in T)
if(G)
if(!G.active)
return
G.cleanup_field(opposite_direction)
break
else
steps++
if(!G || !steps) //no shield gen or no tiles between us and the gen
return
for(var/i in 1 to steps) //creates each field tile
T = get_step(T, opposite_direction)
new/obj/machinery/shieldwall(T, src, G)
return TRUE
/obj/machinery/shieldwallgen/proc/cleanup_field(direction)
var/obj/machinery/shieldwall/F
var/obj/machinery/shieldwallgen/G
var/turf/T = loc
for(var/i in 1 to shield_range)
T = get_step(T, direction)
G = (locate(/obj/machinery/shieldwallgen) in T)
if(G && !G.active)
break
F = (locate(/obj/machinery/shieldwall) in T)
if(F && (F.gen_primary == src || F.gen_secondary == src)) //it's ours, kill it.
qdel(F)
/obj/machinery/shieldwallgen/can_be_unfasten_wrench(mob/user, silent)
if(active)
if(!silent)
to_chat(user, "<span class='warning'>Turn off the shield generator first!</span>")
return FAILED_UNFASTEN
return ..()
/obj/machinery/shieldwallgen/attackby(obj/item/W, mob/user, params)
if(W.tool_behaviour == TOOL_WRENCH)
default_unfasten_wrench(user, W, 0)
else if(W.GetID())
if(allowed(user) && !(obj_flags & EMAGGED))
locked = !locked
to_chat(user, "<span class='notice'>You [src.locked ? "lock" : "unlock"] the controls.</span>")
else if(obj_flags & EMAGGED)
to_chat(user, "<span class='danger'>Error, access controller damaged!</span>")
else
to_chat(user, "<span class='danger'>Access denied.</span>")
else
add_fingerprint(user)
return ..()
/obj/machinery/shieldwallgen/interact(mob/user)
. = ..()
if(.)
return
if(!anchored)
to_chat(user, "<span class='warning'>\The [src] needs to be firmly secured to the floor first!</span>")
return
if(locked && !hasSiliconAccessInArea(user))
to_chat(user, "<span class='warning'>The controls are locked!</span>")
return
if(!power)
to_chat(user, "<span class='warning'>\The [src] needs to be powered by a wire!</span>")
return
if(active)
user.visible_message("[user] turned \the [src] off.", \
"<span class='notice'>You turn off \the [src].</span>", \
"<span class='italics'>You hear heavy droning fade out.</span>")
active = FALSE
update_activity()
else
user.visible_message("[user] turned \the [src] on.", \
"<span class='notice'>You turn on \the [src].</span>", \
"<span class='italics'>You hear heavy droning.</span>")
active = ACTIVE_SETUPFIELDS
update_activity()
add_fingerprint(user)
/obj/machinery/shieldwallgen/emag_act(mob/user)
. = ..()
if(obj_flags & EMAGGED)
to_chat(user, "<span class='warning'>The access controller is damaged!</span>")
return
obj_flags |= EMAGGED
locked = FALSE
playsound(src, "sparks", 100, 1)
to_chat(user, "<span class='warning'>You short out the access controller.</span>")
return TRUE
//////////////Containment Field START
/obj/machinery/shieldwall
name = "shield wall"
desc = "An energy shield."
icon = 'icons/effects/effects.dmi'
icon_state = "shieldwall"
density = TRUE
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
light_range = 3
var/needs_power = FALSE
var/obj/machinery/shieldwallgen/gen_primary
var/obj/machinery/shieldwallgen/gen_secondary
/obj/machinery/shieldwall/Initialize(mapload, obj/machinery/shieldwallgen/first_gen, obj/machinery/shieldwallgen/second_gen)
. = ..()
gen_primary = first_gen
gen_secondary = second_gen
if(gen_primary && gen_secondary)
needs_power = TRUE
setDir(get_dir(gen_primary, gen_secondary))
for(var/mob/living/L in get_turf(src))
visible_message("<span class='danger'>\The [src] is suddenly occupying the same space as \the [L]!</span>")
L.gib()
/obj/machinery/shieldwall/Destroy()
gen_primary = null
gen_secondary = null
return ..()
/obj/machinery/shieldwall/process()
if(needs_power)
if(!gen_primary || !gen_primary.active || !gen_secondary || !gen_secondary.active)
qdel(src)
return
drain_power(10)
/obj/machinery/shieldwall/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BURN)
playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
if(BRUTE)
playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
//the shield wall is immune to damage but it drains the stored power of the generators.
/obj/machinery/shieldwall/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
if(damage_type == BRUTE || damage_type == BURN)
drain_power(damage_amount)
/obj/machinery/shieldwall/proc/drain_power(drain_amount)
if(needs_power && gen_primary)
gen_primary.use_stored_power(drain_amount*0.5)
if(gen_secondary) //using power may cause us to be destroyed
gen_secondary.use_stored_power(drain_amount*0.5)
/obj/machinery/shieldwall/CanAllowThrough(atom/movable/mover, turf/target)
. = ..()
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return prob(20)
else
if(istype(mover, /obj/item/projectile))
return prob(10)