mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-24 09:02:27 +00:00
Emergency energy shields have had their health reduced to 75, down from 200.
Attacking emergency energy shields now play an animation. The less HP they have, the more transparent they become.
You can now use a multitool on engineering tape to mark it as an emergency shield target. An emergency shield generator will deploy shields over it.
351 lines
9.5 KiB
Plaintext
351 lines
9.5 KiB
Plaintext
/obj/machinery/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
|
|
opacity = FALSE
|
|
anchored = TRUE
|
|
unacidable = TRUE
|
|
atmos_canpass = CANPASS_NEVER
|
|
var/health = 75 //The shield can only take so much beating (prevents perma-prisons)
|
|
var/shield_generate_power = 2500 //how much power we use when regenerating
|
|
var/shield_idle_power = 500 //how much power we use when just being sustained.
|
|
|
|
/obj/machinery/shield/malfai
|
|
name = "emergency forcefield"
|
|
desc = "A forcefield which seems to be projected by the station's emergency atmosphere containment field."
|
|
health = 100
|
|
|
|
/obj/machinery/shield/malfai/machinery_process()
|
|
health -= 0.5 // Slowly lose integrity over time
|
|
check_failure()
|
|
|
|
/obj/machinery/shield/proc/check_failure()
|
|
var/health_percentage = (health / initial(health)) * 100
|
|
switch(health_percentage)
|
|
if(-INFINITY to 25)
|
|
if(alpha != 150)
|
|
animate(src, 1 SECOND, alpha = 150)
|
|
if(26 to 50)
|
|
if(alpha != 175)
|
|
animate(src, 1 SECOND, alpha = 175)
|
|
if(51 to 75)
|
|
if(alpha != 210)
|
|
animate(src, 1 SECOND, alpha = 210)
|
|
if(76 to 90)
|
|
if(alpha != 230)
|
|
animate(src, 1 SECOND, alpha = 230)
|
|
if(91 to INFINITY)
|
|
if(alpha != initial(alpha))
|
|
animate(src, 1 SECOND, alpha = initial(alpha))
|
|
if(health <= 0)
|
|
visible_message("<span class='notice'>\The [src] dissipates!</span>")
|
|
qdel(src)
|
|
return
|
|
|
|
/obj/machinery/shield/New()
|
|
src.set_dir(pick(1,2,3,4))
|
|
..()
|
|
update_nearby_tiles(need_rebuild=1)
|
|
|
|
/obj/machinery/shield/Destroy()
|
|
opacity = FALSE
|
|
density = FALSE
|
|
update_nearby_tiles()
|
|
return ..()
|
|
|
|
/obj/machinery/shield/CanPass(atom/movable/mover, turf/target, height, air_group)
|
|
if(!height || air_group) return FALSE
|
|
else return ..()
|
|
|
|
/obj/machinery/shield/attackby(obj/item/W, mob/user)
|
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
|
user.do_attack_animation(src, W)
|
|
//Calculate damage
|
|
var/aforce = W.force
|
|
if(W.damtype == BRUTE || W.damtype == BURN)
|
|
health -= aforce
|
|
|
|
//Play a fitting sound
|
|
playsound(src.loc, 'sound/effects/EMPulse.ogg', 75, 1)
|
|
|
|
check_failure()
|
|
|
|
..()
|
|
|
|
/obj/machinery/shield/bullet_act(var/obj/item/projectile/Proj)
|
|
health -= Proj.get_structure_damage()
|
|
..()
|
|
check_failure()
|
|
opacity = 1
|
|
spawn(20) if(src) opacity = FALSE
|
|
|
|
/obj/machinery/shield/ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
if (prob(75))
|
|
qdel(src)
|
|
if(2.0)
|
|
if (prob(50))
|
|
qdel(src)
|
|
if(3.0)
|
|
if (prob(25))
|
|
qdel(src)
|
|
return
|
|
|
|
/obj/machinery/shield/emp_act(severity)
|
|
switch(severity)
|
|
if(1)
|
|
qdel(src)
|
|
if(2)
|
|
if(prob(50))
|
|
qdel(src)
|
|
|
|
|
|
/obj/machinery/shield/hitby(AM as mob|obj)
|
|
//Let everyone know we've been hit!
|
|
visible_message("<span class='notice'><B>\[src] was hit by [AM].</B></span>")
|
|
|
|
//Super realistic, resource-intensive, real-time damage calculations.
|
|
var/tforce = 0
|
|
if(ismob(AM))
|
|
tforce = 40
|
|
else
|
|
tforce = AM:throwforce
|
|
|
|
src.health -= tforce
|
|
|
|
//This seemed to be the best sound for hitting a force field.
|
|
playsound(src.loc, 'sound/effects/EMPulse.ogg', 100, 1)
|
|
|
|
check_failure()
|
|
|
|
//The shield becomes dense to absorb the blow.. purely asthetic.
|
|
opacity = TRUE
|
|
spawn(20) if(src) opacity = FALSE
|
|
|
|
..()
|
|
return
|
|
|
|
/obj/machinery/shieldgen
|
|
name = "emergency shield projector"
|
|
desc = "Used to seal minor hull breaches."
|
|
icon = 'icons/obj/machines/shielding.dmi'
|
|
icon_state = "shieldoff"
|
|
density = TRUE
|
|
opacity = FALSE
|
|
anchored = FALSE
|
|
req_access = list(access_engine)
|
|
var/health = 100
|
|
var/active = FALSE
|
|
var/malfunction = FALSE //Malfunction causes parts of the shield to slowly dissapate
|
|
var/list/deployed_shields = list()
|
|
var/list/regenerating = list()
|
|
var/is_open = FALSE //Whether or not the wires are exposed
|
|
var/locked = FALSE
|
|
var/check_delay = 60 //periodically recheck if we need to rebuild a shield
|
|
use_power = 0
|
|
idle_power_usage = 0
|
|
|
|
/obj/machinery/shieldgen/Destroy()
|
|
collapse_shields()
|
|
return ..()
|
|
|
|
/obj/machinery/shieldgen/proc/shields_up()
|
|
if(active) return FALSE //If it's already turned on, how did this get called?
|
|
|
|
src.active = 1
|
|
update_icon()
|
|
|
|
create_shields()
|
|
|
|
idle_power_usage = 0
|
|
for(var/obj/machinery/shield/shield_tile in deployed_shields)
|
|
idle_power_usage += shield_tile.shield_idle_power
|
|
update_use_power(TRUE)
|
|
|
|
/obj/machinery/shieldgen/proc/shields_down()
|
|
if(!active) return FALSE //If it's already off, how did this get called?
|
|
|
|
src.active = FALSE
|
|
update_icon()
|
|
|
|
collapse_shields()
|
|
|
|
update_use_power(FALSE)
|
|
|
|
/obj/machinery/shieldgen/proc/create_shields()
|
|
for(var/T in RANGE_TURFS(2, src))
|
|
var/turf/target_tile = T
|
|
var/obj/item/tape/engineering/E = locate() in target_tile
|
|
if(E?.shield_marker)
|
|
deploy_shield(target_tile)
|
|
else if(istype(target_tile,/turf/space) || istype(target_tile,/turf/simulated/open) || istype(target_tile,/turf/unsimulated/floor/asteroid/ash) || istype(target_tile,/turf/simulated/floor/airless) && !(locate(/obj/machinery/shield) in target_tile))
|
|
if(malfunction && prob(33) || !malfunction)
|
|
deploy_shield(target_tile)
|
|
|
|
/obj/machinery/shieldgen/proc/deploy_shield(var/turf/T)
|
|
var/obj/machinery/shield/S = new /obj/machinery/shield(T)
|
|
deployed_shields += S
|
|
use_power(S.shield_generate_power)
|
|
|
|
/obj/machinery/shieldgen/proc/collapse_shields()
|
|
for(var/obj/machinery/shield/shield_tile in deployed_shields)
|
|
qdel(shield_tile)
|
|
|
|
/obj/machinery/shieldgen/power_change()
|
|
..()
|
|
if(!active) return
|
|
if (stat & NOPOWER)
|
|
collapse_shields()
|
|
else
|
|
create_shields()
|
|
update_icon()
|
|
|
|
/obj/machinery/shieldgen/machinery_process()
|
|
if (!active || (stat & NOPOWER))
|
|
return
|
|
|
|
if(malfunction)
|
|
if(deployed_shields.len && prob(5))
|
|
qdel(pick(deployed_shields))
|
|
else
|
|
if (check_delay <= 0)
|
|
create_shields()
|
|
|
|
var/new_power_usage = 0
|
|
for(var/obj/machinery/shield/shield_tile in deployed_shields)
|
|
new_power_usage += shield_tile.shield_idle_power
|
|
|
|
if (new_power_usage != idle_power_usage)
|
|
idle_power_usage = new_power_usage
|
|
use_power(0)
|
|
|
|
check_delay = 60
|
|
else
|
|
check_delay--
|
|
|
|
/obj/machinery/shieldgen/proc/checkhp()
|
|
if(health <= 30)
|
|
src.malfunction = 1
|
|
if(health <= 0)
|
|
spawn(0)
|
|
explosion(get_turf(src.loc), 0, 0, 1, 0, 0, 0)
|
|
qdel(src)
|
|
update_icon()
|
|
return
|
|
|
|
/obj/machinery/shieldgen/ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
src.health -= 75
|
|
src.checkhp()
|
|
if(2.0)
|
|
src.health -= 30
|
|
if (prob(15))
|
|
src.malfunction = 1
|
|
src.checkhp()
|
|
if(3.0)
|
|
src.health -= 10
|
|
src.checkhp()
|
|
return
|
|
|
|
/obj/machinery/shieldgen/emp_act(severity)
|
|
switch(severity)
|
|
if(1)
|
|
src.health /= 2 //cut health in half
|
|
malfunction = TRUE
|
|
locked = pick(0,1)
|
|
if(2)
|
|
if(prob(50))
|
|
src.health *= 0.3 //chop off a third of the health
|
|
malfunction = TRUE
|
|
checkhp()
|
|
|
|
/obj/machinery/shieldgen/attack_hand(mob/user)
|
|
if(locked)
|
|
to_chat(user, SPAN_WARNING("The machine is locked!"))
|
|
return
|
|
if(is_open)
|
|
to_chat(user, SPAN_WARNING("The panel must be closed before operating this machine."))
|
|
return
|
|
|
|
if (src.active)
|
|
user.visible_message("<span class='notice'>[icon2html(src, viewers(get_turf(src)))] [user] deactivates the shield generator.</span>", \
|
|
"<span class='notice'>[icon2html(src, viewers(get_turf(src)))] You deactivate the shield generator.</span>", \
|
|
"You hear heavy droning fade out.")
|
|
src.shields_down()
|
|
else
|
|
if(anchored)
|
|
user.visible_message("<span class='notice'>[icon2html(src, viewers(get_turf(src)))] [user] activate the shield generator.</span>", \
|
|
"<span class='notice'>[icon2html(src, viewers(get_turf(src)))] You activate the shield generator.</span>", \
|
|
"You hear heavy droning.")
|
|
src.shields_up()
|
|
else
|
|
to_chat(user, SPAN_WARNING("The device must first be secured to the floor."))
|
|
return
|
|
|
|
/obj/machinery/shieldgen/emag_act(var/remaining_charges, var/mob/user)
|
|
if(!malfunction)
|
|
malfunction = TRUE
|
|
update_icon()
|
|
return 1
|
|
|
|
/obj/machinery/shieldgen/attackby(obj/item/W as obj, mob/user as mob)
|
|
if(W.isscrewdriver())
|
|
playsound(src.loc, W.usesound, 100, 1)
|
|
if(is_open)
|
|
to_chat(user, "<span class='notice'>You close the panel.</span>")
|
|
is_open = FALSE
|
|
else
|
|
to_chat(user, "<span class='notice'>You open the panel and expose the wiring.</span>")
|
|
is_open = TRUE
|
|
|
|
else if(W.iscoil() && malfunction && is_open)
|
|
var/obj/item/stack/cable_coil/coil = W
|
|
to_chat(user, "<span class='notice'>You begin to replace the wires.</span>")
|
|
//if(do_after(user, min(60, round( ((maxhealth/health)*10)+(malfunction*10) ))) //Take longer to repair heavier damage
|
|
if(do_after(user, 30))
|
|
if (coil.use(1))
|
|
health = initial(health)
|
|
malfunction = FALSE
|
|
to_chat(user, "<span class='notice'>You repair the [src]!</span>")
|
|
update_icon()
|
|
|
|
else if(W.iswrench())
|
|
if(locked)
|
|
to_chat(user, "The bolts are covered, unlocking this would retract the covers.")
|
|
return
|
|
if(anchored)
|
|
playsound(src.loc, W.usesound, 100, 1)
|
|
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>")
|
|
src.shields_down()
|
|
anchored = FALSE
|
|
else
|
|
if(istype(get_turf(src), /turf/space)) return //No wrenching these in space!
|
|
playsound(src.loc, W.usesound, 100, 1)
|
|
to_chat(user, "<span class='notice'>You secure the [src] to the floor!</span>")
|
|
anchored = TRUE
|
|
|
|
|
|
else if(W.GetID())
|
|
if(src.allowed(user))
|
|
src.locked = !src.locked
|
|
to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]")
|
|
else
|
|
to_chat(user, "<span class='warning'>Access denied.</span>")
|
|
|
|
else
|
|
..()
|
|
|
|
|
|
/obj/machinery/shieldgen/update_icon()
|
|
if(active && !(stat & NOPOWER))
|
|
src.icon_state = malfunction ? "shieldonbr":"shieldon"
|
|
else
|
|
src.icon_state = malfunction ? "shieldoffbr":"shieldoff"
|
|
return
|