mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Reorganizes shieldgen source code and icon files
This commit is contained in:
78
code/modules/shieldgen/circuits_and_designs.dm
Normal file
78
code/modules/shieldgen/circuits_and_designs.dm
Normal file
@@ -0,0 +1,78 @@
|
||||
|
||||
////////////////////////////////////////
|
||||
// External Shield Generator
|
||||
|
||||
/obj/item/weapon/circuitboard/shield_gen_ex
|
||||
name = "Circuit board (Hull shield generator)"
|
||||
board_type = "machine"
|
||||
build_path = "/obj/machinery/shield_gen/external"
|
||||
origin_tech = "bluespace=4;phorontech=3"
|
||||
frame_desc = "Requires 2 Pico Manipulators, 1 Subspace Transmitter, 5 Pieces of cable, 1 Subspace Crystal, 1 Subspace Amplifier and 1 Console Screen."
|
||||
req_components = list(
|
||||
"/obj/item/weapon/stock_parts/manipulator/pico" = 2,
|
||||
"/obj/item/weapon/stock_parts/subspace/transmitter" = 1,
|
||||
"/obj/item/weapon/stock_parts/subspace/crystal" = 1,
|
||||
"/obj/item/weapon/stock_parts/subspace/amplifier" = 1,
|
||||
"/obj/item/weapon/stock_parts/console_screen" = 1,
|
||||
"/obj/item/weapon/cable_coil" = 5)
|
||||
|
||||
datum/design/shield_gen_ex
|
||||
name = "Circuit Design (Experimental hull shield generator)"
|
||||
desc = "Allows for the construction of circuit boards used to build an experimental hull shield generator."
|
||||
id = "shield_gen"
|
||||
req_tech = list("bluespace" = 4, "phorontech" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list("$glass" = 2000, "sacid" = 20, "$phoron" = 10000, "$diamond" = 5000, "$gold" = 10000)
|
||||
build_path = "/obj/machinery/shield_gen/external"
|
||||
|
||||
////////////////////////////////////////
|
||||
// Shield Generator
|
||||
|
||||
/obj/item/weapon/circuitboard/shield_gen
|
||||
name = "Circuit board (Bubble shield generator)"
|
||||
board_type = "machine"
|
||||
build_path = "/obj/machinery/shield_gen/external"
|
||||
origin_tech = "bluespace=4;phorontech=3"
|
||||
frame_desc = "Requires 2 Pico Manipulators, 1 Subspace Transmitter, 5 Pieces of cable, 1 Subspace Crystal, 1 Subspace Amplifier and 1 Console Screen."
|
||||
req_components = list(
|
||||
"/obj/item/weapon/stock_parts/manipulator/pico" = 2,
|
||||
"/obj/item/weapon/stock_parts/subspace/transmitter" = 1,
|
||||
"/obj/item/weapon/stock_parts/subspace/crystal" = 1,
|
||||
"/obj/item/weapon/stock_parts/subspace/amplifier" = 1,
|
||||
"/obj/item/weapon/stock_parts/console_screen" = 1,
|
||||
"/obj/item/weapon/cable_coil" = 5)
|
||||
|
||||
datum/design/shield_gen
|
||||
name = "Circuit Design (Bubble shield generator)"
|
||||
desc = "Allows for the construction of circuit boards used to build an experimental shield generator."
|
||||
id = "shield_gen"
|
||||
req_tech = list("bluespace" = 4, "phorontech" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list("$glass" = 2000, "sacid" = 20, "$phoron" = 10000, "$diamond" = 5000, "$gold" = 10000)
|
||||
build_path = "/obj/machinery/shield_gen/external"
|
||||
|
||||
////////////////////////////////////////
|
||||
// Shield Capacitor
|
||||
|
||||
/obj/item/weapon/circuitboard/shield_cap
|
||||
name = "Circuit board (Shield capacitor)"
|
||||
board_type = "machine"
|
||||
build_path = "/obj/machinery/shield_capacitor"
|
||||
origin_tech = "magnets=3;powerstorage=4"
|
||||
frame_desc = "Requires 2 Pico Manipulators, 1 Subspace Filter, 5 Pieces of cable, 1 Subspace Treatment disk, 1 Subspace Analyzer and 1 Console Screen."
|
||||
req_components = list(
|
||||
"/obj/item/weapon/stock_parts/manipulator/pico" = 2,
|
||||
"/obj/item/weapon/stock_parts/subspace/filter" = 1,
|
||||
"/obj/item/weapon/stock_parts/subspace/treatment" = 1,
|
||||
"/obj/item/weapon/stock_parts/subspace/analyzer" = 1,
|
||||
"/obj/item/weapon/stock_parts/console_screen" = 1,
|
||||
"/obj/item/weapon/cable_coil" = 5)
|
||||
|
||||
datum/design/shield_cap
|
||||
name = "Circuit Design (Shield capacitor)"
|
||||
desc = "Allows for the construction of circuit boards used to build an experimental shielding capacitor."
|
||||
id = "shield_cap"
|
||||
req_tech = list("magnets" = 3, "powerstorage" = 4)
|
||||
build_type = IMPRINTER
|
||||
materials = list("$glass" = 2000, "sacid" = 20, "$phoron" = 10000, "$diamond" = 5000, "$silver" = 10000)
|
||||
build_path = "/obj/machinery/shield_gen/external"
|
||||
348
code/modules/shieldgen/emergency_shield.dm
Normal file
348
code/modules/shieldgen/emergency_shield.dm
Normal file
@@ -0,0 +1,348 @@
|
||||
/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 = 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)
|
||||
var/shield_generate_power = 7500 //how much power we use when regenerating
|
||||
var/shield_idle_power = 1500 //how much power we use when just being sustained.
|
||||
|
||||
/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
|
||||
|
||||
air_master.mark_for_update(get_turf(src))
|
||||
|
||||
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, 'sound/effects/EMPulse.ogg', 75, 1)
|
||||
|
||||
|
||||
if (src.health <= 0)
|
||||
visible_message("\blue The [src] dissipates!")
|
||||
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)
|
||||
visible_message("\blue The [src] dissipates!")
|
||||
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)
|
||||
visible_message("\blue The [src] dissipates!")
|
||||
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!
|
||||
visible_message("\red <B>[src] was hit by [AM].</B>")
|
||||
|
||||
//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)
|
||||
|
||||
//Handle the destruction of the shield
|
||||
if (src.health <= 0)
|
||||
visible_message("\blue The [src] dissipates!")
|
||||
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 = 'icons/obj/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/list/regenerating = list()
|
||||
var/is_open = 0 //Whether or not the wires are exposed
|
||||
var/locked = 0
|
||||
var/check_delay = 60 //periodically recheck if we need to rebuild a shield
|
||||
use_power = 0
|
||||
idle_power_usage = 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()
|
||||
|
||||
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(1)
|
||||
|
||||
/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)
|
||||
|
||||
update_use_power(0)
|
||||
|
||||
/obj/machinery/shieldgen/proc/create_shields()
|
||||
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)
|
||||
var/obj/machinery/shield/S = new/obj/machinery/shield(target_tile)
|
||||
deployed_shields += S
|
||||
use_power(S.shield_generate_power)
|
||||
|
||||
/obj/machinery/shieldgen/process()
|
||||
if (!active)
|
||||
return
|
||||
|
||||
if(malfunction)
|
||||
if(deployed_shields.len && prob(5))
|
||||
del(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)
|
||||
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, 'sound/items/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, 'sound/items/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, 'sound/items/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
|
||||
61
code/modules/shieldgen/energy_field.dm
Normal file
61
code/modules/shieldgen/energy_field.dm
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
//---------- actual energy field
|
||||
|
||||
/obj/effect/energy_field
|
||||
name = "energy field"
|
||||
desc = "Impenetrable field of energy, capable of blocking anything as long as it's active."
|
||||
icon = 'icons/obj/machines/shielding.dmi'
|
||||
icon_state = "shieldsparkles"
|
||||
anchored = 1
|
||||
layer = 4.1 //just above mobs
|
||||
density = 0
|
||||
invisibility = 101
|
||||
var/strength = 0
|
||||
var/ticks_recovering = 10
|
||||
|
||||
/obj/effect/energy_field/ex_act(var/severity)
|
||||
Stress(0.5 + severity)
|
||||
|
||||
/obj/effect/energy_field/bullet_act(var/obj/item/projectile/Proj)
|
||||
Stress(Proj.damage / 10)
|
||||
|
||||
/obj/effect/energy_field/meteorhit(obj/effect/meteor/M as obj)
|
||||
if(M)
|
||||
walk(M,0)
|
||||
Stress(2)
|
||||
|
||||
/obj/effect/energy_field/proc/Stress(var/severity)
|
||||
strength -= severity
|
||||
|
||||
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
||||
ticks_recovering = min(ticks_recovering + 2, 10)
|
||||
if(strength < 1)
|
||||
invisibility = 101
|
||||
density = 0
|
||||
ticks_recovering = 10
|
||||
strength = 0
|
||||
else if(strength >= 1)
|
||||
invisibility = 0
|
||||
density = 1
|
||||
|
||||
/obj/effect/energy_field/proc/Strengthen(var/severity)
|
||||
strength += severity
|
||||
if (strength < 0)
|
||||
strength = 0
|
||||
|
||||
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
||||
if(strength >= 1)
|
||||
invisibility = 0
|
||||
density = 1
|
||||
else if(strength < 1)
|
||||
invisibility = 101
|
||||
density = 0
|
||||
|
||||
/obj/effect/energy_field/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
//Purpose: Determines if the object (or airflow) can pass this atom.
|
||||
//Called by: Movement, airflow.
|
||||
//Inputs: The moving atom (optional), target turf, "height" and air group
|
||||
//Outputs: Boolean if can pass.
|
||||
|
||||
//return (!density || !height || air_group)
|
||||
return !density
|
||||
324
code/modules/shieldgen/sheldwallgen.dm
Normal file
324
code/modules/shieldgen/sheldwallgen.dm
Normal file
@@ -0,0 +1,324 @@
|
||||
////FIELD GEN START //shameless copypasta from fieldgen, powersink, and grille
|
||||
/obj/machinery/shieldwallgen
|
||||
name = "Shield Generator"
|
||||
desc = "A shield generator."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "Shield_Gen"
|
||||
anchored = 0
|
||||
density = 1
|
||||
req_access = list(access_teleporter)
|
||||
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
|
||||
//There have to be at least two posts, so these are effectively doubled
|
||||
var/power_draw = 30000 //30 kW. How much power is drawn from powernet. Increase this to allow the generator to sustain longer shields, at the cost of more power draw.
|
||||
var/max_stored_power = 50000 //50 kW
|
||||
use_power = 0 //Draws directly from power net. Does not use 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.")
|
||||
for(var/dir in list(1,2,4,8)) src.cleanup(dir)
|
||||
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/proc/power()
|
||||
if(!anchored)
|
||||
power = 0
|
||||
return 0
|
||||
var/turf/T = src.loc
|
||||
|
||||
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)
|
||||
power = 0
|
||||
return 0
|
||||
|
||||
var/shieldload = between(500, max_stored_power - storedpower, power_draw) //what we try to draw
|
||||
shieldload = PN.draw_power(shieldload) //what we actually get
|
||||
storedpower += shieldload
|
||||
|
||||
//If we're still in the red, then there must not be enough available power to cover our load.
|
||||
if(storedpower <= 0)
|
||||
power = 0
|
||||
return 0
|
||||
|
||||
power = 1 // IVE GOT THE POWER!
|
||||
return 1
|
||||
|
||||
/obj/machinery/shieldwallgen/process()
|
||||
spawn(100)
|
||||
power()
|
||||
if(power)
|
||||
storedpower -= 2500 //the generator post itself uses some power
|
||||
if(storedpower >= max_stored_power)
|
||||
storedpower = max_stored_power
|
||||
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
|
||||
for(var/dir in list(1,2,4,8)) src.cleanup(dir)
|
||||
|
||||
/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, 'sound/items/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, 'sound/items/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)
|
||||
visible_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 -= 400 * Proj.damage
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
//////////////Containment Field START
|
||||
/obj/machinery/shieldwall
|
||||
name = "Shield"
|
||||
desc = "An energy shield."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "shieldwall"
|
||||
anchored = 1
|
||||
density = 1
|
||||
unacidable = 1
|
||||
luminosity = 3
|
||||
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
|
||||
var/power_usage = 2500 //how much power it takes to sustain the shield
|
||||
var/generate_power_usage = 7500 //how much power it takes to start up the shield
|
||||
|
||||
/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 && A.active && B.active)
|
||||
needs_power = 1
|
||||
if(prob(50))
|
||||
A.storedpower -= generate_power_usage
|
||||
else
|
||||
B.storedpower -= generate_power_usage
|
||||
else
|
||||
del(src) //need at least two generator posts
|
||||
|
||||
/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 -= power_usage
|
||||
else
|
||||
gen_secondary.storedpower -= power_usage
|
||||
|
||||
|
||||
/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 -= 400 * Proj.damage
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/shieldwall/ex_act(severity)
|
||||
if(needs_power)
|
||||
var/obj/machinery/shieldwallgen/G
|
||||
switch(severity)
|
||||
if(1.0) //big boom
|
||||
if(prob(50))
|
||||
G = gen_primary
|
||||
else
|
||||
G = gen_secondary
|
||||
G.storedpower -= 120000
|
||||
|
||||
if(2.0) //medium boom
|
||||
if(prob(50))
|
||||
G = gen_primary
|
||||
else
|
||||
G = gen_secondary
|
||||
G.storedpower -= 30000
|
||||
|
||||
if(3.0) //lil boom
|
||||
if(prob(50))
|
||||
G = gen_primary
|
||||
else
|
||||
G = gen_secondary
|
||||
G.storedpower -= 12000
|
||||
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
|
||||
159
code/modules/shieldgen/shield_capacitor.dm
Normal file
159
code/modules/shieldgen/shield_capacitor.dm
Normal file
@@ -0,0 +1,159 @@
|
||||
|
||||
//---------- shield capacitor
|
||||
//pulls energy out of a power net and charges an adjacent generator
|
||||
|
||||
/obj/machinery/shield_capacitor
|
||||
name = "shield capacitor"
|
||||
desc = "Machine that charges a shield generator."
|
||||
icon = 'icons/obj/machines/shielding.dmi'
|
||||
icon_state = "capacitor"
|
||||
var/active = 0
|
||||
density = 1
|
||||
var/stored_charge = 0 //not to be confused with power cell charge, this is in Joules
|
||||
var/last_stored_charge = 0
|
||||
var/time_since_fail = 100
|
||||
var/max_charge = 8e6 //8 MJ
|
||||
var/max_charge_rate = 400000 //400 kW
|
||||
var/locked = 0
|
||||
use_power = 0 //doesn't use APC power
|
||||
var/charge_rate = 100000 //100 kW
|
||||
var/obj/machinery/shield_gen/owned_gen
|
||||
|
||||
/obj/machinery/shield_capacitor/New()
|
||||
spawn(10)
|
||||
for(var/obj/machinery/shield_gen/possible_gen in range(1, src))
|
||||
if(get_dir(src, possible_gen) == src.dir)
|
||||
possible_gen.owned_capacitor = src
|
||||
break
|
||||
..()
|
||||
|
||||
/obj/machinery/shield_capacitor/attackby(obj/item/W, mob/user)
|
||||
|
||||
if(istype(W, /obj/item/weapon/card/id))
|
||||
var/obj/item/weapon/card/id/C = W
|
||||
if(access_captain in C.access || access_security in C.access || access_engine in C.access)
|
||||
src.locked = !src.locked
|
||||
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
|
||||
updateDialog()
|
||||
else
|
||||
user << "\red Access denied."
|
||||
else if(istype(W, /obj/item/weapon/card/emag))
|
||||
if(prob(75))
|
||||
src.locked = !src.locked
|
||||
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
|
||||
updateDialog()
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/wrench))
|
||||
src.anchored = !src.anchored
|
||||
src.visible_message("\blue \icon[src] [src] has been [anchored ? "bolted to the floor" : "unbolted from the floor"] by [user].")
|
||||
|
||||
if(anchored)
|
||||
spawn(0)
|
||||
for(var/obj/machinery/shield_gen/gen in range(1, src))
|
||||
if(get_dir(src, gen) == src.dir && !gen.owned_capacitor)
|
||||
owned_gen = gen
|
||||
owned_gen.owned_capacitor = src
|
||||
owned_gen.updateDialog()
|
||||
else
|
||||
if(owned_gen && owned_gen.owned_capacitor == src)
|
||||
owned_gen.owned_capacitor = null
|
||||
owned_gen = null
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/shield_capacitor/attack_paw(user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/shield_capacitor/attack_ai(user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/shield_capacitor/attack_hand(mob/user)
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/shield_capacitor/interact(mob/user)
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN)) )
|
||||
if (!istype(user, /mob/living/silicon))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=shield_capacitor")
|
||||
return
|
||||
var/t = "<B>Shield Capacitor Control Console</B><br><br>"
|
||||
if(locked)
|
||||
t += "<i>Swipe your ID card to begin.</i>"
|
||||
else
|
||||
t += "This capacitor is: [active ? "<font color=green>Online</font>" : "<font color=red>Offline</font>" ] <a href='?src=\ref[src];toggle=1'>[active ? "\[Deactivate\]" : "\[Activate\]"]</a><br>"
|
||||
t += "Capacitor Status: [time_since_fail > 2 ? "<font color=green>OK.</font>" : "<font color=red>Discharging!</font>"]<br>"
|
||||
t += "Stored Energy: [round(stored_charge/1000, 0.1)] kJ ([100 * round(stored_charge/max_charge, 0.1)]%)<br>"
|
||||
t += "Charge Rate: \
|
||||
<a href='?src=\ref[src];charge_rate=-100000'>\[----\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=-10000'>\[---\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=-1000'>\[--\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=-100'>\[-\]</a>[charge_rate] W \
|
||||
<a href='?src=\ref[src];charge_rate=100'>\[+\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=1000'>\[++\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=10000'>\[+++\]</a> \
|
||||
<a href='?src=\ref[src];charge_rate=100000'>\[+++\]</a><br>"
|
||||
t += "<hr>"
|
||||
t += "<A href='?src=\ref[src]'>Refresh</A> "
|
||||
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
|
||||
|
||||
user << browse(t, "window=shield_capacitor;size=500x400")
|
||||
user.set_machine(src)
|
||||
|
||||
/obj/machinery/shield_capacitor/process()
|
||||
if (!anchored)
|
||||
active = 0
|
||||
|
||||
//see if we can connect to a power net.
|
||||
var/datum/powernet/PN
|
||||
var/turf/T = src.loc
|
||||
var/obj/structure/cable/C = T.get_cable_node()
|
||||
if (C)
|
||||
PN = C.powernet
|
||||
|
||||
if (PN)
|
||||
var/power_draw = between(0, max_charge - stored_charge, charge_rate) //what we are trying to draw
|
||||
power_draw = PN.draw_power(power_draw) //what we actually get
|
||||
stored_charge += power_draw
|
||||
|
||||
time_since_fail++
|
||||
if(stored_charge < last_stored_charge)
|
||||
time_since_fail = 0 //losing charge faster than we can draw from PN
|
||||
last_stored_charge = stored_charge
|
||||
|
||||
/obj/machinery/shield_capacitor/Topic(href, href_list[])
|
||||
..()
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=shield_capacitor")
|
||||
usr.unset_machine()
|
||||
return
|
||||
if( href_list["toggle"] )
|
||||
if(!active && !anchored)
|
||||
usr << "\red The [src] needs to be firmly secured to the floor first."
|
||||
return
|
||||
active = !active
|
||||
if( href_list["charge_rate"] )
|
||||
charge_rate = between(10000, charge_rate + text2num(href_list["charge_rate"]), max_charge_rate)
|
||||
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/shield_capacitor/power_change()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "broke"
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/shield_capacitor/verb/rotate()
|
||||
set name = "Rotate capacitor clockwise"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if (src.anchored)
|
||||
usr << "It is fastened to the floor!"
|
||||
return
|
||||
src.dir = turn(src.dir, 270)
|
||||
return
|
||||
259
code/modules/shieldgen/shield_gen.dm
Normal file
259
code/modules/shieldgen/shield_gen.dm
Normal file
@@ -0,0 +1,259 @@
|
||||
//renwicks: fictional unit to describe shield strength
|
||||
//a small meteor hit will deduct 1 renwick of strength from that shield tile
|
||||
//light explosion range will do 1 renwick's damage
|
||||
//medium explosion range will do 2 renwick's damage
|
||||
//heavy explosion range will do 3 renwick's damage
|
||||
//explosion damage is cumulative. if a tile is in range of light, medium and heavy damage, it will take a hit from all three
|
||||
|
||||
/obj/machinery/shield_gen
|
||||
name = "bubble shield generator"
|
||||
desc = "Machine that generates an impenetrable field of energy when activated."
|
||||
icon = 'icons/obj/machines/shielding.dmi'
|
||||
icon_state = "generator0"
|
||||
var/active = 0
|
||||
var/field_radius = 3
|
||||
var/max_field_radius = 100
|
||||
var/list/field
|
||||
density = 1
|
||||
var/locked = 0
|
||||
var/average_field_strength = 0
|
||||
var/strengthen_rate = 0.2
|
||||
var/max_strengthen_rate = 0.5 //the maximum rate that the generator can increase the average field strength
|
||||
var/dissipation_rate = 0.030 //the percentage of the shield strength that needs to be replaced each second
|
||||
var/min_dissipation = 0.1 //will dissipate by at least this rate in renwicks per field tile (otherwise field would never dissipate completely as dissipation is a percentage)
|
||||
var/powered = 0
|
||||
var/check_powered = 1
|
||||
var/obj/machinery/shield_capacitor/owned_capacitor
|
||||
var/target_field_strength = 10
|
||||
var/max_field_strength = 10
|
||||
var/time_since_fail = 100
|
||||
var/energy_conversion_rate = 0.0002 //how many renwicks per watt?
|
||||
use_power = 0 //doesn't use APC power
|
||||
|
||||
/obj/machinery/shield_gen/New()
|
||||
spawn(10)
|
||||
for(var/obj/machinery/shield_capacitor/possible_cap in range(1, src))
|
||||
if(get_dir(possible_cap, src) == possible_cap.dir)
|
||||
owned_capacitor = possible_cap
|
||||
break
|
||||
field = new/list()
|
||||
..()
|
||||
|
||||
/obj/machinery/shield_gen/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/weapon/card/id))
|
||||
var/obj/item/weapon/card/id/C = W
|
||||
if(access_captain in C.access || access_security in C.access || access_engine in C.access)
|
||||
src.locked = !src.locked
|
||||
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
|
||||
updateDialog()
|
||||
else
|
||||
user << "\red Access denied."
|
||||
else if(istype(W, /obj/item/weapon/card/emag))
|
||||
if(prob(75))
|
||||
src.locked = !src.locked
|
||||
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
|
||||
updateDialog()
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/wrench))
|
||||
src.anchored = !src.anchored
|
||||
src.visible_message("\blue \icon[src] [src] has been [anchored?"bolted to the floor":"unbolted from the floor"] by [user].")
|
||||
|
||||
if(active)
|
||||
toggle()
|
||||
if(anchored)
|
||||
spawn(0)
|
||||
for(var/obj/machinery/shield_capacitor/cap in range(1, src))
|
||||
if(cap.owned_gen)
|
||||
continue
|
||||
if(get_dir(cap, src) == cap.dir && src.anchored)
|
||||
owned_capacitor = cap
|
||||
owned_capacitor.owned_gen = src
|
||||
updateDialog()
|
||||
break
|
||||
else
|
||||
if(owned_capacitor && owned_capacitor.owned_gen == src)
|
||||
owned_capacitor.owned_gen = null
|
||||
owned_capacitor = null
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/shield_gen/attack_paw(user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/shield_gen/attack_ai(user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/shield_gen/attack_hand(mob/user)
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/shield_gen/interact(mob/user)
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN)) )
|
||||
if (!istype(user, /mob/living/silicon))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=shield_generator")
|
||||
return
|
||||
var/t = "<B>Shield Generator Control Console</B><BR><br>"
|
||||
if(locked)
|
||||
t += "<i>Swipe your ID card to begin.</i>"
|
||||
else
|
||||
t += "[owned_capacitor ? "<font color=green>Charge capacitor connected.</font>" : "<font color=red>Unable to locate charge capacitor!</font>"]<br>"
|
||||
t += "This generator is: [active ? "<font color=green>Online</font>" : "<font color=red>Offline</font>" ] <a href='?src=\ref[src];toggle=1'>[active ? "\[Deactivate\]" : "\[Activate\]"]</a><br>"
|
||||
t += "Field Status: [time_since_fail > 2 ? "<font color=green>Stable</font>" : "<font color=red>Unstable</font>"]<br>"
|
||||
t += "Coverage Radius (restart required): \
|
||||
<a href='?src=\ref[src];change_radius=-50'>---</a> \
|
||||
<a href='?src=\ref[src];change_radius=-5'>--</a> \
|
||||
<a href='?src=\ref[src];change_radius=-1'>-</a> \
|
||||
[field_radius] m \
|
||||
<a href='?src=\ref[src];change_radius=1'>+</a> \
|
||||
<a href='?src=\ref[src];change_radius=5'>++</a> \
|
||||
<a href='?src=\ref[src];change_radius=50'>+++</a><br>"
|
||||
t += "Overall Field Strength: [round(average_field_strength, 0.01)] Renwick ([target_field_strength ? round(100 * average_field_strength / target_field_strength, 0.1) : "NA"]%)<br>"
|
||||
t += "Upkeep Power: [round(field.len * max(average_field_strength * dissipation_rate, min_dissipation) / energy_conversion_rate)] W<br>"
|
||||
t += "Charge Rate: <a href='?src=\ref[src];strengthen_rate=-0.1'>--</a> \
|
||||
[strengthen_rate] Renwick/s \
|
||||
<a href='?src=\ref[src];strengthen_rate=0.1'>++</a><br>"
|
||||
t += "Shield Generation Power: [round(field.len * min(strengthen_rate, target_field_strength - average_field_strength) / energy_conversion_rate)] W<br>"
|
||||
t += "Maximum Field Strength: \
|
||||
<a href='?src=\ref[src];target_field_strength=-10'>\[min\]</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=-5'>--</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=-1'>-</a> \
|
||||
[target_field_strength] Renwick \
|
||||
<a href='?src=\ref[src];target_field_strength=1'>+</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=5'>++</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=10'>\[max\]</a><br>"
|
||||
t += "<hr>"
|
||||
t += "<A href='?src=\ref[src]'>Refresh</A> "
|
||||
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
|
||||
user << browse(t, "window=shield_generator;size=500x400")
|
||||
user.set_machine(src)
|
||||
|
||||
/obj/machinery/shield_gen/process()
|
||||
if (!anchored && active)
|
||||
toggle()
|
||||
|
||||
average_field_strength = max(average_field_strength, 0)
|
||||
|
||||
if(field.len)
|
||||
time_since_fail++
|
||||
var/total_renwick_increase = 0 //the amount of renwicks that the generator can add this tick, over the entire field
|
||||
var/renwick_upkeep_per_field = max(average_field_strength * dissipation_rate, min_dissipation)
|
||||
|
||||
//figure out how much energy we need to draw from the capacitor
|
||||
if(active && owned_capacitor && owned_capacitor.active)
|
||||
var/target_renwick_increase = min(target_field_strength - average_field_strength, strengthen_rate) + renwick_upkeep_per_field //per field tile
|
||||
|
||||
var/required_energy = field.len * target_renwick_increase / energy_conversion_rate
|
||||
var/assumed_charge = min(owned_capacitor.stored_charge, required_energy)
|
||||
total_renwick_increase = assumed_charge * energy_conversion_rate
|
||||
owned_capacitor.stored_charge -= assumed_charge
|
||||
else
|
||||
renwick_upkeep_per_field = max(renwick_upkeep_per_field, 0.5)
|
||||
|
||||
var/renwick_increase_per_field = total_renwick_increase/field.len //per field tile
|
||||
|
||||
average_field_strength = 0 //recalculate the average field strength
|
||||
for(var/obj/effect/energy_field/E in field)
|
||||
var/amount_to_strengthen = renwick_increase_per_field - renwick_upkeep_per_field
|
||||
if(E.ticks_recovering > 0 && amount_to_strengthen > 0)
|
||||
E.Strengthen( min(amount_to_strengthen / 10, 0.1) )
|
||||
E.ticks_recovering -= 1
|
||||
else
|
||||
E.Strengthen(amount_to_strengthen)
|
||||
|
||||
average_field_strength += E.strength
|
||||
|
||||
average_field_strength /= field.len
|
||||
if(average_field_strength < 1)
|
||||
time_since_fail = 0
|
||||
else
|
||||
average_field_strength = 0
|
||||
|
||||
/obj/machinery/shield_gen/Topic(href, href_list[])
|
||||
..()
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=shield_generator")
|
||||
usr.unset_machine()
|
||||
return
|
||||
else if( href_list["toggle"] )
|
||||
if (!active && !anchored)
|
||||
usr << "\red The [src] needs to be firmly secured to the floor first."
|
||||
return
|
||||
toggle()
|
||||
else if( href_list["change_radius"] )
|
||||
field_radius = between(0, field_radius + text2num(href_list["change_radius"]), max_field_radius)
|
||||
else if( href_list["strengthen_rate"] )
|
||||
strengthen_rate = between(0, strengthen_rate + text2num(href_list["strengthen_rate"]), max_strengthen_rate)
|
||||
else if( href_list["target_field_strength"] )
|
||||
target_field_strength = between(1, target_field_strength + text2num(href_list["target_field_strength"]), max_field_strength)
|
||||
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/shield_gen/ex_act(var/severity)
|
||||
|
||||
if(active)
|
||||
toggle()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/shield_gen/proc/toggle()
|
||||
set background = 1
|
||||
active = !active
|
||||
update_icon()
|
||||
if(active)
|
||||
var/list/covered_turfs = get_shielded_turfs()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T in covered_turfs)
|
||||
covered_turfs.Remove(T)
|
||||
for(var/turf/O in covered_turfs)
|
||||
var/obj/effect/energy_field/E = new(O)
|
||||
field.Add(E)
|
||||
del covered_turfs
|
||||
|
||||
for(var/mob/M in view(5,src))
|
||||
M << "\icon[src] You hear heavy droning start up."
|
||||
else
|
||||
for(var/obj/effect/energy_field/D in field)
|
||||
field.Remove(D)
|
||||
D.loc = null
|
||||
|
||||
for(var/mob/M in view(5,src))
|
||||
M << "\icon[src] You hear heavy droning fade out."
|
||||
|
||||
/obj/machinery/shield_gen/update_icon()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "broke"
|
||||
else
|
||||
if (src.active)
|
||||
icon_state = "generator1"
|
||||
else
|
||||
icon_state = "generator0"
|
||||
|
||||
//TODO MAKE THIS MULTIZ COMPATIBLE
|
||||
//grab the border tiles in a circle around this machine
|
||||
/obj/machinery/shield_gen/proc/get_shielded_turfs()
|
||||
var/list/out = list()
|
||||
|
||||
var/turf/gen_turf = get_turf(src)
|
||||
if (!gen_turf)
|
||||
return
|
||||
|
||||
var/turf/T
|
||||
for (var/x_offset = -field_radius; x_offset <= field_radius; x_offset++)
|
||||
T = locate(gen_turf.x + x_offset, gen_turf.y - field_radius, gen_turf.z)
|
||||
if (T) out += T
|
||||
|
||||
T = locate(gen_turf.x + x_offset, gen_turf.y + field_radius, gen_turf.z)
|
||||
if (T) out += T
|
||||
|
||||
for (var/y_offset = -field_radius+1; y_offset < field_radius; y_offset++)
|
||||
T = locate(gen_turf.x - field_radius, gen_turf.y + y_offset, gen_turf.z)
|
||||
if (T) out += T
|
||||
|
||||
T = locate(gen_turf.x + field_radius, gen_turf.y + y_offset, gen_turf.z)
|
||||
if (T) out += T
|
||||
|
||||
return out
|
||||
27
code/modules/shieldgen/shield_gen_external.dm
Normal file
27
code/modules/shieldgen/shield_gen_external.dm
Normal file
@@ -0,0 +1,27 @@
|
||||
//---------- external shield generator
|
||||
//generates an energy field that loops around any built up area in space (is useless inside) halts movement and airflow, is blocked by walls, windows, airlocks etc
|
||||
|
||||
/obj/machinery/shield_gen/external
|
||||
name = "hull shield generator"
|
||||
|
||||
/obj/machinery/shield_gen/external/New()
|
||||
..()
|
||||
|
||||
//NOT MULTIZ COMPATIBLE
|
||||
//Search for space turfs within range that are adjacent to a simulated turf.
|
||||
/obj/machinery/shield_gen/external/get_shielded_turfs()
|
||||
var/list/out = list()
|
||||
|
||||
var/turf/gen_turf = get_turf(src)
|
||||
if (!gen_turf)
|
||||
return
|
||||
|
||||
var/turf/T
|
||||
for (var/x_offset = -field_radius; x_offset <= field_radius; x_offset++)
|
||||
for (var/y_offset = -field_radius; y_offset <= field_radius; y_offset++)
|
||||
T = locate(gen_turf.x + x_offset, gen_turf.y + y_offset, gen_turf.z)
|
||||
if (istype(T, /turf/space))
|
||||
//check neighbors of T
|
||||
if (locate(/turf/simulated/) in orange(1, T))
|
||||
out += T
|
||||
return out
|
||||
Reference in New Issue
Block a user