/obj/machinery/shield name = "Emergency energy shield" desc = "An energy shield used to contain hull breaches." icon = 'effects.dmi' icon_state = "shield-old" density = 1 opacity = 0 anchored = 1 unacidable = 1 var/const/max_health = 200 var/health = max_health //The shield can only take so much beating (prevents perma-prisons) /obj/machinery/shield/New() src.dir = pick(1,2,3,4) ..() update_nearby_tiles(need_rebuild=1) /obj/machinery/shield/Del() opacity = 0 density = 0 update_nearby_tiles() ..() /obj/machinery/shield/CanPass(atom/movable/mover, turf/target, height, air_group) if(!height || air_group) return 0 else return ..() //Looks like copy/pasted code... I doubt 'need_rebuild' is even used here - Nodrak /obj/machinery/shield/proc/update_nearby_tiles(need_rebuild) if(!air_master) return 0 var/turf/simulated/source = loc var/turf/simulated/north = get_step(source,NORTH) var/turf/simulated/south = get_step(source,SOUTH) var/turf/simulated/east = get_step(source,EAST) var/turf/simulated/west = get_step(source,WEST) if(need_rebuild) if(istype(source)) //Rebuild/update nearby group geometry if(source.parent) air_master.groups_to_rebuild += source.parent else air_master.tiles_to_update += source if(istype(north)) if(north.parent) air_master.groups_to_rebuild += north.parent else air_master.tiles_to_update += north if(istype(south)) if(south.parent) air_master.groups_to_rebuild += south.parent else air_master.tiles_to_update += south if(istype(east)) if(east.parent) air_master.groups_to_rebuild += east.parent else air_master.tiles_to_update += east if(istype(west)) if(west.parent) air_master.groups_to_rebuild += west.parent else air_master.tiles_to_update += west else if(istype(source)) air_master.tiles_to_update += source if(istype(north)) air_master.tiles_to_update += north if(istype(south)) air_master.tiles_to_update += south if(istype(east)) air_master.tiles_to_update += east if(istype(west)) air_master.tiles_to_update += west return 1 /obj/machinery/shield/attackby(obj/item/weapon/W as obj, mob/user as mob) if(!istype(W)) return //Calculate damage var/aforce = W.force if(W.damtype == BRUTE || W.damtype == BURN) src.health -= aforce //Play a fitting sound playsound(src.loc, 'EMPulse.ogg', 75, 1) if (src.health <= 0) for(var/mob/O in viewers(src, null)) O.show_message("\blue The [src] dissapates") del(src) return opacity = 1 spawn(20) if(src) opacity = 0 ..() /obj/machinery/shield/meteorhit() src.health -= max_health*0.75 //3/4 health as damage if(src.health <= 0) for(var/mob/O in viewers(src, null)) O.show_message("\blue The [src] dissapates") del(src) return opacity = 1 spawn(20) if(src) opacity = 0 return /obj/machinery/shield/bullet_act(var/obj/item/projectile/Proj) health -= Proj.damage ..() if(health <=0) for(var/mob/O in viewers(src, null)) O.show_message("\blue The [src] dissapates") del(src) return opacity = 1 spawn(20) if(src) opacity = 0 /obj/machinery/shield/ex_act(severity) switch(severity) if(1.0) if (prob(75)) del(src) if(2.0) if (prob(50)) del(src) if(3.0) if (prob(25)) del(src) return /obj/machinery/shield/emp_act(severity) switch(severity) if(1) del(src) if(2) if(prob(50)) del(src) /obj/machinery/shield/blob_act() del(src) /obj/machinery/shield/hitby(AM as mob|obj) //Let everyone know we've been hit! for(var/mob/O in viewers(src, null)) O.show_message("\red [src] was hit by [AM].", 1) //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, 'EMPulse.ogg', 100, 1) //Handle the destruction of the shield if (src.health <= 0) for(var/mob/O in viewers(src, null)) O.show_message("\blue The [src] dissapates") del(src) return //The shield becomes dense to absorb the blow.. purely asthetic. opacity = 1 spawn(20) if(src) opacity = 0 ..() return /obj/machinery/shieldgen name = "Emergency shield projector" desc = "Used to seal minor hull breaches." icon = 'objects.dmi' icon_state = "shieldoff" density = 1 opacity = 0 anchored = 0 pressure_resistance = 2*ONE_ATMOSPHERE req_access = list(access_engine) var/const/max_health = 100 var/health = max_health var/active = 0 var/malfunction = 0 //Malfunction causes parts of the shield to slowly dissapate var/list/deployed_shields = list() var/is_open = 0 //Whether or not the wires are exposed var/locked = 0 /obj/machinery/shieldgen/Del() for(var/obj/machinery/shield/shield_tile in deployed_shields) del(shield_tile) ..() /obj/machinery/shieldgen/proc/shields_up() if(active) return 0 //If it's already turned on, how did this get called? src.active = 1 update_icon() for(var/turf/target_tile in range(2, src)) if (istype(target_tile,/turf/space) && !(locate(/obj/machinery/shield) in target_tile)) if (malfunction && prob(33) || !malfunction) deployed_shields += new /obj/machinery/shield(target_tile) /obj/machinery/shieldgen/proc/shields_down() if(!active) return 0 //If it's already off, how did this get called? src.active = 0 update_icon() for(var/obj/machinery/shield/shield_tile in deployed_shields) del(shield_tile) /obj/machinery/shieldgen/process() if(malfunction && active) if(deployed_shields && prob(5)) del(pick(deployed_shields)) return /obj/machinery/shieldgen/proc/checkhp() if(health <= 30) src.malfunction = 1 if(health <= 0) del(src) update_icon() return /obj/machinery/shieldgen/meteorhit(obj/O as obj) src.health -= max_health*0.25 //A quarter of the machine's health if (prob(5)) src.malfunction = 1 src.checkhp() 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 = 1 locked = pick(0,1) if(2) if(prob(50)) src.health *= 0.3 //chop off a third of the health malfunction = 1 checkhp() /obj/machinery/shieldgen/attack_hand(mob/user as mob) if(locked) user << "The machine is locked, you are unable to use it." return if(is_open) user << "The panel must be closed before operating this machine." return if (src.active) user.visible_message("\blue \icon[src] [user] deactivated the shield generator.", \ "\blue \icon[src] You deactivate the shield generator.", \ "You hear heavy droning fade out.") src.shields_down() else if(anchored) user.visible_message("\blue \icon[src] [user] activated the shield generator.", \ "\blue \icon[src] You activate the shield generator.", \ "You hear heavy droning.") src.shields_up() else user << "The device must first be secured to the floor." return /obj/machinery/shieldgen/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/card/emag)) malfunction = 1 update_icon() else if(istype(W, /obj/item/weapon/screwdriver)) playsound(src.loc, 'Screwdriver.ogg', 100, 1) if(is_open) user << "\blue You close the panel." is_open = 0 else user << "\blue You open the panel and expose the wiring." is_open = 1 else if(istype(W, /obj/item/weapon/cable_coil) && malfunction && is_open) var/obj/item/weapon/cable_coil/coil = W user << "\blue You begin to replace the wires." //if(do_after(user, min(60, round( ((maxhealth/health)*10)+(malfunction*10) ))) //Take longer to repair heavier damage if(do_after(user, 30)) if(!src || !coil) return coil.use(1) health = max_health malfunction = 0 user << "\blue You repair the [src]!" update_icon() else if(istype(W, /obj/item/weapon/wrench)) if(locked) user << "The bolts are covered, unlocking this would retract the covers." return if(anchored) playsound(src.loc, 'Ratchet.ogg', 100, 1) user << "\blue You unsecure the [src] from the floor!" if(active) user << "\blue The [src] shuts off!" src.shields_down() anchored = 0 else if(istype(get_turf(src), /turf/space)) return //No wrenching these in space! playsound(src.loc, 'Ratchet.ogg', 100, 1) user << "\blue You secure the [src] to the floor!" anchored = 1 else if(istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda)) if(src.allowed(user)) src.locked = !src.locked user << "The controls are now [src.locked ? "locked." : "unlocked."]" else user << "\red Access denied." else ..() /obj/machinery/shieldgen/update_icon() if(active) src.icon_state = malfunction ? "shieldonbr":"shieldon" else src.icon_state = malfunction ? "shieldoffbr":"shieldoff" return ////FIELD GEN START //shameless copypasta from fieldgen, powersink, and grille #define maxstoredpower 500 /obj/machinery/shieldwallgen name = "Shield Generator" desc = "A shield generator." icon = 'stationobjs.dmi' icon_state = "Shield_Gen" anchored = 0 density = 1 req_access = list(access_security) var/active = 0 var/power = 0 var/state = 0 var/steps = 0 var/last_check = 0 var/check_delay = 10 var/recalc = 0 var/locked = 1 var/destroyed = 0 var/directwired = 1 // var/maxshieldload = 200 var/obj/structure/cable/attached // the attached cable var/storedpower = 0 flags = FPRINT | CONDUCT use_power = 0 /obj/machinery/shieldwallgen/proc/power() if(!anchored) power = 0 return 0 var/turf/T = src.loc var/obj/structure/cable/C = T.get_cable_node() var/net if (C) net = C.netnum // find the powernet of the connected cable if(!net) power = 0 return 0 var/datum/powernet/PN = powernets[net] // find the powernet. Magic code, voodoo code. if(!PN) power = 0 return 0 var/surplus = max(PN.avail-PN.load, 0) var/shieldload = min(rand(50,200), surplus) if(shieldload==0 && !storedpower) // no cable or no power, and no power stored power = 0 return 0 else power = 1 // IVE GOT THE POWER! if(PN) //runtime errors fixer. They were caused by PN.newload trying to access missing network in case of working on stored power. storedpower += shieldload PN.newload += shieldload //uses powernet power. // message_admins("[PN.load]", 1) // use_power(250) //uses APC power /obj/machinery/shieldwallgen/attack_hand(mob/user as mob) if(state != 1) user << "\red The shield generator needs to be firmly secured to the floor first." return 1 if(src.locked && !istype(user, /mob/living/silicon)) user << "\red The controls are locked!" return 1 if(power != 1) user << "\red The shield generator needs to be powered by wire underneath." return 1 if(src.active >= 1) src.active = 0 icon_state = "Shield_Gen" user.visible_message("[user] turned the shield generator off.", \ "You turn off the shield generator.", \ "You hear heavy droning fade out.") src.cleanup() else src.active = 1 icon_state = "Shield_Gen +a" user.visible_message("[user] turned the shield generator on.", \ "You turn on the shield generator.", \ "You hear heavy droning.") src.add_fingerprint(user) /obj/machinery/shieldwallgen/process() spawn(100) power() if(power) storedpower -= 50 //this way it can survive longer and survive at all if(storedpower >= maxstoredpower) storedpower = maxstoredpower if(storedpower <= 0) storedpower = 0 // if(shieldload >= maxshieldload) //there was a loop caused by specifics of process(), so this was needed. // shieldload = maxshieldload if(src.active == 1) if(!src.state == 1) src.active = 0 return spawn(1) setup_field(1) spawn(2) setup_field(2) spawn(3) setup_field(4) spawn(4) setup_field(8) src.active = 2 if(src.active >= 1) if(src.power == 0) src.visible_message("\red The [src.name] shuts down due to lack of power!", \ "You hear heavy droning fade out") icon_state = "Shield_Gen" src.active = 0 spawn(1) src.cleanup(1) spawn(1) src.cleanup(2) spawn(1) src.cleanup(4) spawn(1) src.cleanup(8) /obj/machinery/shieldwallgen/proc/setup_field(var/NSEW = 0) var/turf/T = src.loc var/turf/T2 = src.loc var/obj/machinery/shieldwallgen/G var/steps = 0 var/oNSEW = 0 if(!NSEW)//Make sure its ran right return if(NSEW == 1) oNSEW = 2 else if(NSEW == 2) oNSEW = 1 else if(NSEW == 4) oNSEW = 8 else if(NSEW == 8) oNSEW = 4 for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for another generator T = get_step(T2, NSEW) T2 = T steps += 1 if(locate(/obj/machinery/shieldwallgen) in T) G = (locate(/obj/machinery/shieldwallgen) in T) steps -= 1 if(!G.active) return G.cleanup(oNSEW) break if(isnull(G)) return T2 = src.loc for(var/dist = 0, dist < steps, dist += 1) // creates each field tile var/field_dir = get_dir(T2,get_step(T2, NSEW)) T = get_step(T2, NSEW) T2 = T var/obj/machinery/shieldwall/CF = new/obj/machinery/shieldwall/(src, G) //(ref to this gen, ref to connected gen) CF.loc = T CF.dir = field_dir /obj/machinery/shieldwallgen/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/weapon/wrench)) if(active) user << "Turn off the field generator first." return else if(state == 0) state = 1 playsound(src.loc, 'Ratchet.ogg', 75, 1) user << "You secure the external reinforcing bolts to the floor." src.anchored = 1 return else if(state == 1) state = 0 playsound(src.loc, 'Ratchet.ogg', 75, 1) user << "You undo the external reinforcing bolts." src.anchored = 0 return if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if (src.allowed(user)) src.locked = !src.locked user << "Controls are now [src.locked ? "locked." : "unlocked."]" else user << "\red Access denied." else src.add_fingerprint(user) user << "\red You hit the [src.name] with your [W.name]!" for(var/mob/M in viewers(src)) if(M == user) continue M.show_message("\red The [src.name] has been hit with the [W.name] by [user.name]!") /obj/machinery/shieldwallgen/proc/cleanup(var/NSEW) var/obj/machinery/shieldwall/F var/obj/machinery/shieldwallgen/G var/turf/T = src.loc var/turf/T2 = src.loc for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for fields T = get_step(T2, NSEW) T2 = T if(locate(/obj/machinery/shieldwall) in T) F = (locate(/obj/machinery/shieldwall) in T) del(F) if(locate(/obj/machinery/shieldwallgen) in T) G = (locate(/obj/machinery/shieldwallgen) in T) if(!G.active) break /obj/machinery/shieldwallgen/Del() src.cleanup(1) src.cleanup(2) src.cleanup(4) src.cleanup(8) ..() /obj/machinery/shieldwallgen/bullet_act(var/obj/item/projectile/Proj) storedpower -= Proj.damage ..() return //////////////Contaiment Field START /obj/machinery/shieldwall name = "Shield" desc = "An energy shield." icon = 'effects.dmi' icon_state = "shieldwall" anchored = 1 density = 1 unacidable = 1 var/needs_power = 0 var/active = 1 // var/power = 10 var/delay = 5 var/last_active var/mob/U var/obj/machinery/shieldwallgen/gen_primary var/obj/machinery/shieldwallgen/gen_secondary /obj/machinery/shieldwall/New(var/obj/machinery/shieldwallgen/A, var/obj/machinery/shieldwallgen/B) ..() src.gen_primary = A src.gen_secondary = B if(A && B) needs_power = 1 spawn(1) src.sd_SetLuminosity(3) /obj/machinery/shieldwall/attack_hand(mob/user as mob) return /obj/machinery/shieldwall/process() if(needs_power) if(isnull(gen_primary)||isnull(gen_secondary)) del(src) return if(!(gen_primary.active)||!(gen_secondary.active)) del(src) return // if(prob(50)) gen_primary.storedpower -= 10 else gen_secondary.storedpower -=10 /obj/machinery/shieldwall/bullet_act(var/obj/item/projectile/Proj) if(needs_power) var/obj/machinery/shieldwallgen/G if(prob(50)) G = gen_primary else G = gen_secondary G.storedpower -= Proj.damage ..() return /obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(air_group || (height==0)) return 1 if(istype(mover) && mover.checkpass(PASSGLASS)) return prob(20) else if (istype(mover, /obj/item/projectile)) return prob(10) else return !src.density