mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 02:34:00 +00:00
Merge pull request #5940 from mwerezak/power-net
Update for shield generator power use and power net fixes
This commit is contained in:
@@ -318,7 +318,6 @@
|
||||
#include "code\game\machinery\requests_console.dm"
|
||||
#include "code\game\machinery\robot_fabricator.dm"
|
||||
#include "code\game\machinery\seed_extractor.dm"
|
||||
#include "code\game\machinery\shieldgen.dm"
|
||||
#include "code\game\machinery\Sleeper.dm"
|
||||
#include "code\game\machinery\spaceheater.dm"
|
||||
#include "code\game\machinery\status_display.dm"
|
||||
@@ -1316,6 +1315,13 @@
|
||||
#include "code\modules\scripting\Scanner\Tokens.dm"
|
||||
#include "code\modules\security levels\keycard authentication.dm"
|
||||
#include "code\modules\security levels\security levels.dm"
|
||||
#include "code\modules\shieldgen\circuits_and_designs.dm"
|
||||
#include "code\modules\shieldgen\emergency_shield.dm"
|
||||
#include "code\modules\shieldgen\energy_field.dm"
|
||||
#include "code\modules\shieldgen\sheldwallgen.dm"
|
||||
#include "code\modules\shieldgen\shield_capacitor.dm"
|
||||
#include "code\modules\shieldgen\shield_gen.dm"
|
||||
#include "code\modules\shieldgen\shield_gen_external.dm"
|
||||
#include "code\modules\shuttles\antagonist.dm"
|
||||
#include "code\modules\shuttles\departmental.dm"
|
||||
#include "code\modules\shuttles\shuttle.dm"
|
||||
@@ -1388,11 +1394,6 @@
|
||||
#include "code\WorkInProgress\Cael_Aislinn\Rust\gyrotron_controller.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\Rust\radiation.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\Rust\virtual_particle_catcher.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\ShieldGen\circuits_and_designs.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\ShieldGen\energy_field.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\ShieldGen\shield_capacitor.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\ShieldGen\shield_gen.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\ShieldGen\shield_gen_external.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\LaserComputer.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\ZeroPointLaser.dm"
|
||||
#include "code\WorkInProgress\Chinsky\ashtray.dm"
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
//---------- 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()
|
||||
..()
|
||||
|
||||
/obj/machinery/shield_gen/external/get_shielded_turfs()
|
||||
var
|
||||
list
|
||||
open = list(get_turf(src))
|
||||
closed = list()
|
||||
|
||||
while(open.len)
|
||||
for(var/turf/T in open)
|
||||
for(var/turf/O in orange(1, T))
|
||||
if(get_dist(O,src) > field_radius)
|
||||
continue
|
||||
var/add_this_turf = 0
|
||||
if(istype(O,/turf/space))
|
||||
for(var/turf/simulated/G in orange(1, O))
|
||||
add_this_turf = 1
|
||||
break
|
||||
|
||||
//uncomment this for structures (but not lattices) to be surrounded by shield as well
|
||||
/*if(!add_this_turf)
|
||||
for(var/obj/structure/S in orange(1, O))
|
||||
if(!istype(S, /obj/structure/lattice))
|
||||
add_this_turf = 1
|
||||
break
|
||||
if(add_this_turf)
|
||||
for(var/obj/structure/S in O)
|
||||
if(!istype(S, /obj/structure/lattice))
|
||||
add_this_turf = 0
|
||||
break*/
|
||||
|
||||
if(add_this_turf && !(O in open) && !(O in closed))
|
||||
open += O
|
||||
open -= T
|
||||
closed += T
|
||||
|
||||
return closed
|
||||
@@ -300,7 +300,7 @@ datum/controller/game_controller/proc/process_machines_power()
|
||||
if(M)
|
||||
//check if the area has power for M's channel
|
||||
//this will keep stat updated in case the machine is moved from one area to another.
|
||||
M.update_powered_status(A) //we've already made sure A is a master area, above.
|
||||
M.power_change(A) //we've already made sure A is a master area, above.
|
||||
|
||||
if(!(M.stat & NOPOWER) && M.use_power)
|
||||
M.auto_use_power()
|
||||
|
||||
@@ -276,15 +276,15 @@
|
||||
del(src)
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/power_change()
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "broken"
|
||||
else if(powered())
|
||||
icon_state = initial(icon_state)
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = "c_unpowered"
|
||||
stat |= NOPOWER
|
||||
if (stat & NOPOWER)
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = "c_unpowered"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/New()
|
||||
..()
|
||||
|
||||
@@ -1031,8 +1031,7 @@ ________________________________________________________________________________
|
||||
drain = rand(G.mindrain,G.maxdrain)
|
||||
var/drained = 0
|
||||
if(PN&&do_after(U,10))
|
||||
drained = min(drain, PN.avail)
|
||||
PN.newload += drained
|
||||
drained = PN.draw_power(drain)
|
||||
if(drained < drain)//if no power on net, drain apcs
|
||||
for(var/obj/machinery/power/terminal/T in PN.nodes)
|
||||
if(istype(T.master, /obj/machinery/power/apc))
|
||||
@@ -1083,8 +1082,7 @@ ________________________________________________________________________________
|
||||
drain = (round((rand(G.mindrain,G.maxdrain))/2))
|
||||
var/drained = 0
|
||||
if(PN&&do_after(U,10))
|
||||
drained = min(drain, PN.avail)
|
||||
PN.newload += drained
|
||||
drained = PN.draw_power(drain)
|
||||
if(drained < drain)//if no power on net, drain apcs
|
||||
for(var/obj/machinery/power/terminal/T in PN.nodes)
|
||||
if(istype(T.master, /obj/machinery/power/apc))
|
||||
|
||||
@@ -142,9 +142,6 @@
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/sleep_console/power_change()
|
||||
return
|
||||
// no change - sleeper works without power (you just can't inject more)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -159,15 +159,15 @@
|
||||
del(src)
|
||||
|
||||
/obj/machinery/body_scanconsole/power_change()
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "body_scannerconsole-p"
|
||||
else if(powered())
|
||||
icon_state = initial(icon_state)
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = "body_scannerconsole-p"
|
||||
stat |= NOPOWER
|
||||
if (stat & NOPOWER)
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = "body_scannerconsole-p"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/machinery/body_scanconsole
|
||||
var/obj/machinery/bodyscanner/connected
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
req_access = list(access_ai_upload)
|
||||
|
||||
/obj/machinery/ai_slipper/power_change()
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
else
|
||||
if( powered() )
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
if (stat & NOPOWER)
|
||||
icon_state = "motion0"
|
||||
stat |= NOPOWER
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/machinery/ai_slipper/proc/setState(var/enabled, var/uses)
|
||||
src.disabled = disabled
|
||||
|
||||
@@ -1156,10 +1156,7 @@ table tr:first-child th:first-child { border: none;}
|
||||
return ..()
|
||||
|
||||
/obj/machinery/alarm/power_change()
|
||||
if(powered(power_channel))
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= NOPOWER
|
||||
..()
|
||||
spawn(rand(0,15))
|
||||
update_icon()
|
||||
|
||||
@@ -1367,13 +1364,9 @@ FIRE ALARM
|
||||
return
|
||||
|
||||
/obj/machinery/firealarm/power_change()
|
||||
if(powered(ENVIRON))
|
||||
stat &= ~NOPOWER
|
||||
..()
|
||||
spawn(rand(0,15))
|
||||
update_icon()
|
||||
else
|
||||
spawn(rand(0,15))
|
||||
stat |= NOPOWER
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/firealarm/attack_hand(mob/user as mob)
|
||||
if(user.stat || stat & (NOPOWER|BROKEN))
|
||||
|
||||
@@ -127,15 +127,14 @@
|
||||
|
||||
|
||||
/obj/machinery/power/monitor/power_change()
|
||||
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "broken"
|
||||
else
|
||||
if( powered() )
|
||||
icon_state = initial(icon_state)
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
if (stat & NOPOWER)
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = "c_unpowered"
|
||||
stat |= NOPOWER
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
var/net_id
|
||||
var/list/areas_added
|
||||
var/list/users_to_open
|
||||
|
||||
power_channel = ENVIRON
|
||||
use_power = 1
|
||||
idle_power_usage = 5
|
||||
|
||||
/obj/machinery/door/firedoor/New()
|
||||
. = ..()
|
||||
@@ -66,15 +70,6 @@
|
||||
attack_hand(M)
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/power_change()
|
||||
if(powered(ENVIRON))
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= NOPOWER
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/attack_hand(mob/user as mob)
|
||||
add_fingerprint(user)
|
||||
if(operating)
|
||||
@@ -101,6 +96,9 @@
|
||||
if(user.stat || user.stunned || user.weakened || user.paralysis || (!user.canmove && !isAI(user)) || (get_dist(src, user) > 1 && !isAI(user)))
|
||||
user << "Sorry, you must remain able bodied and close to \the [src] in order to use it."
|
||||
return
|
||||
if(density && (stat & (BROKEN|NOPOWER))) //can still close without power
|
||||
user << "\The [src] is not functioning, you'll have to force it open manually."
|
||||
return
|
||||
|
||||
var/needs_to_close = 0
|
||||
if(density)
|
||||
@@ -163,10 +161,10 @@
|
||||
else
|
||||
user.visible_message("\red \The [user] forces \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \a [C]!",\
|
||||
"You force \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \the [C]!",\
|
||||
"You hear metal strain and groan, and a door [density ? "open" : "close"].")
|
||||
"You hear metal strain and groan, and a door [density ? "opening" : "closing"].")
|
||||
if(density)
|
||||
spawn(0)
|
||||
open()
|
||||
open(1)
|
||||
else
|
||||
spawn(0)
|
||||
close()
|
||||
@@ -175,7 +173,7 @@
|
||||
|
||||
|
||||
/obj/machinery/door/firedoor/proc/latetoggle()
|
||||
if(operating || stat & NOPOWER || !nextstate)
|
||||
if(operating || !nextstate)
|
||||
return
|
||||
switch(nextstate)
|
||||
if(OPEN)
|
||||
@@ -190,7 +188,12 @@
|
||||
latetoggle()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/door/firedoor/open()
|
||||
/obj/machinery/door/firedoor/open(var/forced = 0)
|
||||
if (!forced)
|
||||
if (stat & BROKEN|NOPOWER)
|
||||
return //needs power to open unless it was forced
|
||||
else
|
||||
use_power(360)
|
||||
latetoggle()
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -44,12 +44,11 @@ var/list/doppler_arrays = list()
|
||||
|
||||
|
||||
/obj/machinery/doppler_array/power_change()
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
else
|
||||
if( powered() )
|
||||
if( !(stat & NOPOWER) )
|
||||
icon_state = initial(icon_state)
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
icon_state = "[initial(icon_state)]-off"
|
||||
stat |= NOPOWER
|
||||
icon_state = "[initial(icon_state)]-off"
|
||||
@@ -28,12 +28,11 @@
|
||||
src.sd_SetLuminosity(2)
|
||||
*/
|
||||
/obj/machinery/flasher/power_change()
|
||||
if ( powered() )
|
||||
stat &= ~NOPOWER
|
||||
..()
|
||||
if ( !(stat & NOPOWER) )
|
||||
icon_state = "[base_state]1"
|
||||
// src.sd_SetLuminosity(2)
|
||||
else
|
||||
stat |= ~NOPOWER
|
||||
icon_state = "[base_state]1-p"
|
||||
// src.sd_SetLuminosity(0)
|
||||
|
||||
|
||||
@@ -153,12 +153,6 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
active_power_usage = 100
|
||||
var/obj/effect/overlay/hologram//The projection itself. If there is one, the instrument is on, off otherwise.
|
||||
|
||||
/obj/machinery/hologram/power_change()
|
||||
if (powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= ~NOPOWER
|
||||
|
||||
//Destruction procs.
|
||||
/obj/machinery/hologram/ex_act(severity)
|
||||
switch(severity)
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
icon_state = "igniter[on]"
|
||||
|
||||
/obj/machinery/igniter/power_change()
|
||||
..()
|
||||
if(!( stat & NOPOWER) )
|
||||
icon_state = "igniter[src.on]"
|
||||
else
|
||||
@@ -60,12 +61,12 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/sparker/power_change()
|
||||
if ( powered() && disable == 0 )
|
||||
stat &= ~NOPOWER
|
||||
..()
|
||||
if ( !(stat & NOPOWER) && disable == 0 )
|
||||
|
||||
icon_state = "[base_state]"
|
||||
// src.sd_SetLuminosity(2)
|
||||
else
|
||||
stat |= ~NOPOWER
|
||||
icon_state = "[base_state]-p"
|
||||
// src.sd_SetLuminosity(0)
|
||||
|
||||
|
||||
@@ -118,17 +118,16 @@
|
||||
src.throw_item()
|
||||
|
||||
/obj/machinery/smartfridge/power_change()
|
||||
if( powered() )
|
||||
..()
|
||||
if( !(stat & NOPOWER) )
|
||||
src.ispowered = 1
|
||||
stat &= ~NOPOWER
|
||||
if(!isbroken)
|
||||
icon_state = icon_on
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.ispowered = 0
|
||||
stat |= NOPOWER
|
||||
if(!isbroken)
|
||||
icon_state = icon_off
|
||||
src.ispowered = 0
|
||||
if(!isbroken)
|
||||
icon_state = icon_off
|
||||
|
||||
/*******************
|
||||
* Item Adding
|
||||
|
||||
@@ -138,14 +138,13 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
|
||||
/obj/machinery/newscaster/power_change()
|
||||
if(isbroken) //Broken shit can't be powered.
|
||||
return
|
||||
if( src.powered() )
|
||||
..()
|
||||
if( !(stat & NOPOWER) )
|
||||
src.ispowered = 1
|
||||
stat &= ~NOPOWER
|
||||
src.update_icon()
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.ispowered = 0
|
||||
stat |= NOPOWER
|
||||
src.update_icon()
|
||||
|
||||
|
||||
|
||||
@@ -264,10 +264,12 @@ Status: []<BR>"},
|
||||
if(!anchored)
|
||||
icon_state = "turretCover"
|
||||
return
|
||||
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "[lasercolor]destroyed_target_prism"
|
||||
else
|
||||
if( powered() )
|
||||
if( !(stat & NOPOWER) )
|
||||
if (on)
|
||||
if (installation == /obj/item/weapon/gun/energy/laser || installation == /obj/item/weapon/gun/energy/pulse_rifle)
|
||||
// laser guns and pulse rifles have an orange icon
|
||||
@@ -277,11 +279,9 @@ Status: []<BR>"},
|
||||
icon_state = "[lasercolor]target_prism"
|
||||
else
|
||||
icon_state = "[lasercolor]grey_target_prism"
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = "[lasercolor]grey_target_prism"
|
||||
stat |= NOPOWER
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -28,13 +28,12 @@ obj/machinery/scanner/New()
|
||||
use_power(50)
|
||||
|
||||
/obj/machinery/scanner/power_change()
|
||||
if(!powered())
|
||||
..()
|
||||
if(stat & NOPOWER)
|
||||
spawn(rand(0, 15))
|
||||
icon_state = "scanner_off"
|
||||
stat |= NOPOWER
|
||||
else
|
||||
icon_state = "scanner_idle"
|
||||
stat &= ~NOPOWER
|
||||
|
||||
obj/machinery/scanner/attack_hand(mob/living/carbon/human/user)
|
||||
if(stat & NOPOWER)
|
||||
|
||||
@@ -34,12 +34,6 @@
|
||||
else
|
||||
user << "The robot part maker is full. Please remove metal from the robot part maker in order to insert more."
|
||||
|
||||
/obj/machinery/robotic_fabricator/power_change()
|
||||
if (powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= NOPOWER
|
||||
|
||||
/obj/machinery/robotic_fabricator/attack_paw(user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
|
||||
@@ -1,630 +0,0 @@
|
||||
/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)
|
||||
|
||||
/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/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.len && 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, '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
|
||||
|
||||
////FIELD GEN START //shameless copypasta from fieldgen, powersink, and grille
|
||||
#define maxstoredpower 500
|
||||
/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
|
||||
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/datum/powernet/PN
|
||||
if(C) PN = C.powernet // find the powernet of the connected cable
|
||||
|
||||
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.")
|
||||
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/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
|
||||
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 -= 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
|
||||
|
||||
/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
|
||||
|
||||
/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/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 -= 200
|
||||
|
||||
if(2.0) //medium boom
|
||||
if(prob(50))
|
||||
G = gen_primary
|
||||
else
|
||||
G = gen_secondary
|
||||
G.storedpower -= 50
|
||||
|
||||
if(3.0) //lil boom
|
||||
if(prob(50))
|
||||
G = gen_primary
|
||||
else
|
||||
G = gen_secondary
|
||||
G.storedpower -= 20
|
||||
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
|
||||
@@ -59,14 +59,13 @@
|
||||
|
||||
|
||||
/obj/machinery/suit_storage_unit/power_change()
|
||||
if( powered() )
|
||||
..()
|
||||
if( !(stat & NOPOWER) )
|
||||
src.ispowered = 1
|
||||
stat &= ~NOPOWER
|
||||
src.update_icon()
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.ispowered = 0
|
||||
stat |= NOPOWER
|
||||
src.islocked = 0
|
||||
src.isopen = 1
|
||||
src.dump_everything()
|
||||
|
||||
@@ -93,10 +93,11 @@
|
||||
return (popping!=0)
|
||||
|
||||
/obj/machinery/turret/power_change()
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "grey_target_prism"
|
||||
else
|
||||
if( powered() )
|
||||
if( !(stat & NOPOWER) )
|
||||
if (src.enabled)
|
||||
if (src.lasers)
|
||||
icon_state = "orange_target_prism"
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
var/vend_power_usage = 150 //actuators and stuff
|
||||
|
||||
var/active = 1 //No sales pitches if off!
|
||||
var/delay_product_spawn // If set, uses sleep() in product spawn proc (mostly for seeds to retrieve correct names).
|
||||
@@ -511,7 +512,7 @@
|
||||
src.speak(src.vend_reply)
|
||||
src.last_reply = world.time
|
||||
|
||||
use_power(150) //actuators and stuff
|
||||
use_power(vend_power_usage) //actuators and stuff
|
||||
if (src.icon_vend) //Show the vending animation if needed
|
||||
flick(src.icon_vend,src)
|
||||
spawn(src.vend_delay)
|
||||
@@ -561,16 +562,15 @@
|
||||
return
|
||||
|
||||
/obj/machinery/vending/power_change()
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "[initial(icon_state)]-broken"
|
||||
else
|
||||
if( powered() )
|
||||
if( !(stat & NOPOWER) )
|
||||
icon_state = initial(icon_state)
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = "[initial(icon_state)]-off"
|
||||
stat |= NOPOWER
|
||||
|
||||
//Oh no we're malfunctioning! Dump out some product and break.
|
||||
/obj/machinery/vending/proc/malfunction()
|
||||
@@ -708,6 +708,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe = 2,/obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine = 5)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/tea = 10)
|
||||
vend_delay = 15
|
||||
idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan.
|
||||
product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?"
|
||||
product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!"
|
||||
req_access_txt = "25"
|
||||
@@ -725,6 +726,8 @@
|
||||
icon_state = "coffee"
|
||||
icon_vend = "coffee-vend"
|
||||
vend_delay = 34
|
||||
idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan.
|
||||
vend_power_usage = 85000 //85 kJ to heat a 250 mL cup of coffee
|
||||
products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10)
|
||||
prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25, /obj/item/weapon/reagent_containers/food/drinks/tea = 25, /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25)
|
||||
@@ -763,6 +766,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 2,/obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 1)
|
||||
idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan.
|
||||
|
||||
//This one's from bay12
|
||||
/obj/machinery/vending/cart
|
||||
@@ -802,6 +806,7 @@
|
||||
/obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2,
|
||||
/obj/item/stack/medical/advanced/bruise_pack = 3, /obj/item/stack/medical/advanced/ointment = 3, /obj/item/stack/medical/splint = 2)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6)
|
||||
idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan.
|
||||
|
||||
|
||||
//This one's from bay12
|
||||
@@ -855,6 +860,7 @@
|
||||
products = list(/obj/item/weapon/reagent_containers/glass/fertilizer/ez = 35,/obj/item/weapon/reagent_containers/glass/fertilizer/l4z = 25,/obj/item/weapon/reagent_containers/glass/fertilizer/rh = 15,/obj/item/weapon/plantspray/pests = 20,
|
||||
/obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/storage/bag/plants = 5)
|
||||
premium = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5)
|
||||
idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan.
|
||||
|
||||
/obj/machinery/vending/hydroseeds
|
||||
name = "MegaSeed Servitor"
|
||||
@@ -901,6 +907,7 @@
|
||||
product_ads = "For Tsar and Country.;Have you fulfilled your nutrition quota today?;Very nice!;We are simple people, for this is all we eat.;If there is a person, there is a problem. If there is no person, then there is no problem."
|
||||
products = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/soda = 30)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/cola = 20)
|
||||
idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan.
|
||||
|
||||
/obj/machinery/vending/tool
|
||||
name = "YouTool"
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
shock_damage *= siemens_coeff
|
||||
if (shock_damage<1)
|
||||
return 0
|
||||
|
||||
src.take_overall_damage(0,shock_damage,used_weapon="Electrocution")
|
||||
//src.burn_skin(shock_damage)
|
||||
//src.adjustFireLoss(shock_damage) //burn_skin will do this for us
|
||||
@@ -117,6 +118,11 @@
|
||||
Stun(10)//This should work for now, more is really silly and makes you lay there forever
|
||||
// if(src.weakened < 20*siemens_coeff) src.weakened = 20*siemens_coeff
|
||||
Weaken(10)
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, loc)
|
||||
s.start()
|
||||
|
||||
return shock_damage
|
||||
|
||||
|
||||
|
||||
@@ -19,11 +19,9 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/drone_fabricator/power_change()
|
||||
if (powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
..()
|
||||
if (stat & NOPOWER)
|
||||
icon_state = "drone_fab_nopower"
|
||||
stat |= NOPOWER
|
||||
|
||||
/obj/machinery/drone_fabricator/process()
|
||||
|
||||
|
||||
@@ -37,6 +37,22 @@
|
||||
/mob/living/silicon/stun_effect_act(var/stun_amount, var/agony_amount)
|
||||
return //immune
|
||||
|
||||
/mob/living/silicon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0)
|
||||
|
||||
if (istype(source, /obj/machinery/containment_field))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, loc)
|
||||
s.start()
|
||||
|
||||
shock_damage *= 0.75 //take reduced damage
|
||||
take_overall_damage(0, shock_damage)
|
||||
visible_message("\red [src] was shocked by \the [source]!", \
|
||||
"\red <B>Energy pulse detected, system damaged!</B>", \
|
||||
"\red You hear an electrical crack")
|
||||
if(prob(20))
|
||||
Stun(2)
|
||||
return
|
||||
|
||||
/mob/living/silicon/proc/damage_mob(var/brute = 0, var/fire = 0, var/tox = 0)
|
||||
return
|
||||
|
||||
|
||||
@@ -1144,7 +1144,8 @@
|
||||
|
||||
/obj/machinery/power/apc/add_load(var/amount)
|
||||
if(terminal && terminal.powernet)
|
||||
terminal.powernet.newload += amount
|
||||
return terminal.powernet.draw_power(amount)
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/apc/avail()
|
||||
if(terminal)
|
||||
@@ -1176,13 +1177,7 @@
|
||||
var/last_ch = charging
|
||||
|
||||
var/excess = surplus()
|
||||
|
||||
if(!src.avail())
|
||||
main_status = 0
|
||||
else if(excess < 0)
|
||||
main_status = 1
|
||||
else
|
||||
main_status = 2
|
||||
var/power_excess = 0
|
||||
|
||||
var/perapc = 0
|
||||
if(terminal && terminal.powernet)
|
||||
@@ -1195,36 +1190,35 @@
|
||||
//var/cell_charge = cell.charge
|
||||
var/cell_maxcharge = cell.maxcharge
|
||||
|
||||
// draw power from cell as before
|
||||
|
||||
var/cellused = min(cell.charge, CELLRATE * lastused_total) // clamp deduction to a max, amount left in cell
|
||||
cell.use(cellused)
|
||||
|
||||
if(excess > 0 || perapc > lastused_total) // if power excess, or enough anyway, recharge the cell
|
||||
// by the same amount just used
|
||||
cell.give(cellused)
|
||||
add_load(cellused/CELLRATE) // add the load used to recharge the cell
|
||||
|
||||
|
||||
else // no excess, and not enough per-apc
|
||||
|
||||
if( (cell.charge/CELLRATE+perapc) >= lastused_total) // can we draw enough from cell+grid to cover last usage?
|
||||
|
||||
cell.give(CELLRATE * perapc) //recharge with what we can
|
||||
add_load(perapc) // so draw what we can from the grid
|
||||
// try to draw power from the grid
|
||||
if (!src.avail())
|
||||
main_status = 0
|
||||
else
|
||||
var/power_drawn = add_load(perapc)
|
||||
|
||||
//figure out how much power is left over after meeting demand
|
||||
power_excess = power_drawn - lastused_total
|
||||
|
||||
if (power_excess < 0) //couldn't get enough power from the grid, we will need to take from the power cell.
|
||||
main_status = 1
|
||||
charging = 0
|
||||
|
||||
var/required_power = -power_excess
|
||||
if( (cell.charge/CELLRATE) >= required_power) // can we draw enough from cell to cover what's left over?
|
||||
cell.use(required_power*CELLRATE)
|
||||
|
||||
else if (autoflag != 0) // not enough power available to run the last tick!
|
||||
charging = 0
|
||||
chargecount = 0
|
||||
// This turns everything off in the case that there is still a charge left on the battery, just not enough to run the room.
|
||||
equipment = autoset(equipment, 0)
|
||||
lighting = autoset(lighting, 0)
|
||||
environ = autoset(environ, 0)
|
||||
autoflag = 0
|
||||
else if (autoflag != 0) // not enough power available to run the last tick!
|
||||
chargecount = 0
|
||||
// This turns everything off in the case that there is still a charge left on the battery, just not enough to run the room.
|
||||
equipment = autoset(equipment, 0)
|
||||
lighting = autoset(lighting, 0)
|
||||
environ = autoset(environ, 0)
|
||||
autoflag = 0
|
||||
|
||||
else
|
||||
main_status = 2
|
||||
|
||||
|
||||
// set channels depending on how much charge we have left
|
||||
// Set channels depending on how much charge we have left
|
||||
|
||||
// Allow the APC to operate as normal if the cell can charge
|
||||
if(charging && longtermpower < 10)
|
||||
@@ -1267,10 +1261,9 @@
|
||||
// now trickle-charge the cell
|
||||
|
||||
if(chargemode && charging == 1 && operating)
|
||||
if(excess > 0) // check to make sure we have enough to charge
|
||||
// Max charge is perapc share, capped to cell capacity, or % per second constant (Whichever is smallest)
|
||||
var/ch = min(perapc*CELLRATE, (cell_maxcharge - cell.charge), (cell_maxcharge*CHARGELEVEL))
|
||||
add_load(ch/CELLRATE) // Removes the power we're taking from the grid
|
||||
if(power_excess > 0) // check to make sure we have enough to charge
|
||||
// Max charge is available excess power, capped to cell capacity, or % per second constant (Whichever is smallest)
|
||||
var/ch = min(power_excess*CELLRATE, (cell_maxcharge - cell.charge), (cell_maxcharge*CHARGELEVEL))
|
||||
cell.give(ch) // actually recharge the cell
|
||||
|
||||
else
|
||||
@@ -1278,13 +1271,13 @@
|
||||
chargecount = 0
|
||||
|
||||
// show cell as fully charged if so
|
||||
|
||||
if(cell.charge >= cell_maxcharge)
|
||||
charging = 2
|
||||
|
||||
//if we have excess power for long enough, think about re-enable charging.
|
||||
if(chargemode)
|
||||
if(!charging)
|
||||
if(excess > cell_maxcharge*CHARGELEVEL)
|
||||
if(power_excess*CELLRATE >= cell_maxcharge*CHARGELEVEL)
|
||||
chargecount++
|
||||
else
|
||||
chargecount = 0
|
||||
@@ -1320,21 +1313,21 @@
|
||||
src.updateDialog()
|
||||
|
||||
// val 0=off, 1=off(auto) 2=on 3=on(auto)
|
||||
// on 0=off, 1=on, 2=autooff
|
||||
// on 0=off, 1=auto-on, 2=auto-off
|
||||
|
||||
/proc/autoset(var/val, var/on)
|
||||
|
||||
if(on==0)
|
||||
if(on==0) // turn things off
|
||||
if(val==2) // if on, return off
|
||||
return 0
|
||||
else if(val==3) // if auto-on, return auto-off
|
||||
return 1
|
||||
|
||||
else if(on==1)
|
||||
else if(on==1) // turn things auto-on
|
||||
if(val==1) // if auto-off, return auto-on
|
||||
return 3
|
||||
|
||||
else if(on==2)
|
||||
else if(on==2) // turn things auto-off
|
||||
if(val==3) // if auto-on, return auto-off
|
||||
return 1
|
||||
|
||||
|
||||
@@ -222,8 +222,9 @@
|
||||
if(charging)
|
||||
if(excess >= 0) // if there's power available, try to charge
|
||||
var/load = min((capacity * 1.5 - charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity
|
||||
load = add_load(load) // add the load to the terminal side network
|
||||
charge += load * SMESRATE // increase the charge
|
||||
add_load(load) // add the load to the terminal side network
|
||||
|
||||
|
||||
else // if not enough capacity
|
||||
charging = 0 // stop charging
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
if( !(pn_input.avail >= LOGIC_HIGH))
|
||||
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
|
||||
else
|
||||
pn_output.newload += LOGIC_HIGH //Otherwise increase the load to 5
|
||||
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
|
||||
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
if( (pn_input1.avail >= LOGIC_HIGH) && (pn_input2.avail >= LOGIC_HIGH) )
|
||||
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
|
||||
else
|
||||
pn_output.newload += LOGIC_HIGH //Otherwise increase the load to 5
|
||||
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
|
||||
|
||||
//OR GATE
|
||||
/obj/machinery/logic/twoinput/or/process()
|
||||
@@ -222,7 +222,7 @@
|
||||
if( (pn_input1.avail >= LOGIC_HIGH) || (pn_input2.avail >= LOGIC_HIGH) )
|
||||
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
|
||||
else
|
||||
pn_output.newload += LOGIC_HIGH //Otherwise increase the load to 5
|
||||
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
|
||||
|
||||
//XOR GATE
|
||||
/obj/machinery/logic/twoinput/xor/process()
|
||||
@@ -242,7 +242,7 @@
|
||||
if( (pn_input1.avail >= LOGIC_HIGH) != (pn_input2.avail >= LOGIC_HIGH) )
|
||||
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
|
||||
else
|
||||
pn_output.newload += LOGIC_HIGH //Otherwise increase the load to 5
|
||||
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
|
||||
|
||||
//XNOR GATE (EQUIVALENCE)
|
||||
/obj/machinery/logic/twoinput/xnor/process()
|
||||
@@ -262,7 +262,7 @@
|
||||
if( (pn_input1.avail >= LOGIC_HIGH) == (pn_input2.avail >= LOGIC_HIGH) )
|
||||
pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before.
|
||||
else
|
||||
pn_output.newload += LOGIC_HIGH //Otherwise increase the load to 5
|
||||
pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5
|
||||
|
||||
#define RELAY_POWER_TRANSFER 2000 //How much power a relay transfers through.
|
||||
|
||||
@@ -284,7 +284,7 @@
|
||||
return
|
||||
|
||||
if(pn_input2.avail >= RELAY_POWER_TRANSFER)
|
||||
pn_input2.newload += RELAY_POWER_TRANSFER
|
||||
pn_input2.draw_power(RELAY_POWER_TRANSFER)
|
||||
pn_output.newavail += RELAY_POWER_TRANSFER
|
||||
|
||||
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
|
||||
/obj/machinery/power/proc/add_load(var/amount)
|
||||
if(powernet)
|
||||
powernet.newload += amount
|
||||
return powernet.draw_power(amount)
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/proc/surplus()
|
||||
if(powernet)
|
||||
return powernet.avail-powernet.load
|
||||
return powernet.surplus()
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -67,25 +68,23 @@
|
||||
log_power_update_request(A.master, src)
|
||||
A.master.powerupdate = 2 // Decremented by 2 each GC tick, since it's not auto power change we're going to update power twice.
|
||||
|
||||
/obj/machinery/proc/power_change() // called whenever the power settings of the containing area change
|
||||
//The master_area optional argument can be used to save on a lot of processing if the master area is already known. This is mainly intended for when this proc is called by the master controller.
|
||||
/obj/machinery/proc/power_change(var/area/master_area = null) // called whenever the power settings of the containing area change
|
||||
// by default, check equipment channel & set flag
|
||||
// can override if needed
|
||||
if(powered(power_channel))
|
||||
var/has_power
|
||||
if (master_area)
|
||||
has_power = master_area.powered(power_channel)
|
||||
else
|
||||
has_power = powered(power_channel)
|
||||
|
||||
if(has_power)
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
|
||||
stat |= NOPOWER
|
||||
return
|
||||
|
||||
//This is used by the master controller to update the NOPOWER flag
|
||||
//This will allow machines to update NOPOWER if they are moved from one area to another.
|
||||
//Does the same thing as power_change() but is optimized for the master controller.
|
||||
/obj/machinery/proc/update_powered_status(var/area/master_area)
|
||||
if(master_area.powered(power_channel))
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= NOPOWER
|
||||
|
||||
// the powernet datum
|
||||
// each contiguous network of cables & nodes
|
||||
|
||||
@@ -402,6 +401,19 @@
|
||||
error("[S.name] (\ref[S]) had a [S.powernet ? "different (\ref[S.powernet])" : "null"] powernet to our powernet (\ref[src]).")
|
||||
nodes.Remove(S)
|
||||
|
||||
|
||||
//Returns the amount of available power
|
||||
/datum/powernet/proc/surplus()
|
||||
return max(avail - newload, 0)
|
||||
|
||||
//Attempts to draw power from a powernet. Returns the actual amount of power drawn
|
||||
/datum/powernet/proc/draw_power(var/requested_amount)
|
||||
var/surplus = max(avail - newload, 0)
|
||||
var/actual_draw = min(requested_amount, surplus)
|
||||
newload += actual_draw
|
||||
|
||||
return actual_draw
|
||||
|
||||
/datum/powernet/proc/get_electrocute_damage()
|
||||
switch(avail)/*
|
||||
if (1300000 to INFINITY)
|
||||
@@ -551,11 +563,11 @@
|
||||
var/drained_energy = drained_hp*20
|
||||
|
||||
if (source_area)
|
||||
source_area.use_power(drained_energy/CELLRATE)
|
||||
source_area.use_power(drained_energy)
|
||||
else if (istype(power_source,/datum/powernet))
|
||||
var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts"
|
||||
PN.newload+=drained_power
|
||||
//var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts" <<< NO. THIS IS WRONG. CELLRATE DOES NOT CONVERT TO OR FROM JOULES.
|
||||
PN.draw_power(drained_energy)
|
||||
else if (istype(power_source, /obj/item/weapon/cell))
|
||||
cell.use(drained_energy)
|
||||
cell.use(drained_energy*CELLRATE) //convert to units of charge.
|
||||
return drained_energy
|
||||
|
||||
|
||||
@@ -56,49 +56,17 @@
|
||||
if(!FG1 || !FG2)
|
||||
del(src)
|
||||
return 0
|
||||
if(iscarbon(user))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, user.loc)
|
||||
s.start()
|
||||
|
||||
if(isliving(user))
|
||||
hasShocked = 1
|
||||
var/shock_damage = min(rand(30,40),rand(30,40))
|
||||
user.burn_skin(shock_damage)
|
||||
user.updatehealth()
|
||||
user.visible_message("\red [user.name] was shocked by the [src.name]!", \
|
||||
"\red <B>You feel a powerful shock course through your body sending you flying!</B>", \
|
||||
"\red You hear a heavy electrical crack")
|
||||
user.electrocute_act(shock_damage, src)
|
||||
|
||||
var/stun = min(shock_damage, 15)
|
||||
user.Stun(stun)
|
||||
user.Weaken(10)
|
||||
|
||||
user.updatehealth()
|
||||
var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src)))
|
||||
user.throw_at(target, 200, 4)
|
||||
|
||||
sleep(20)
|
||||
|
||||
hasShocked = 0
|
||||
return
|
||||
|
||||
else if(issilicon(user))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, user.loc)
|
||||
s.start()
|
||||
|
||||
hasShocked = 1
|
||||
var/shock_damage = rand(15,30)
|
||||
user.take_overall_damage(0,shock_damage)
|
||||
user.visible_message("\red [user.name] was shocked by the [src.name]!", \
|
||||
"\red <B>Energy pulse detected, system damaged!</B>", \
|
||||
"\red You hear an electrical crack")
|
||||
if(prob(20))
|
||||
user.Stun(2)
|
||||
|
||||
sleep(20)
|
||||
hasShocked = 0
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/containment_field/proc/set_master(var/master1,var/master2)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
||||
#define EMITTER_DAMAGE_POWER_TRANSFER 350 //used to transfer power to containment field generators
|
||||
|
||||
/obj/machinery/power/emitter
|
||||
name = "Emitter"
|
||||
@@ -10,13 +11,15 @@
|
||||
req_access = list(access_engine_equip)
|
||||
var/id = null
|
||||
|
||||
use_power = 0
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 300
|
||||
use_power = 0 //uses powernet power, not APC power
|
||||
active_power_usage = 30000 //30 kW laser. I guess that means 30 kJ per shot.
|
||||
|
||||
var/active = 0
|
||||
var/powered = 0
|
||||
var/fire_delay = 100
|
||||
var/max_burst_delay = 100
|
||||
var/min_burst_delay = 20
|
||||
var/burst_shots = 3
|
||||
var/last_shot = 0
|
||||
var/shot_number = 0
|
||||
var/state = 0
|
||||
@@ -104,8 +107,7 @@
|
||||
return
|
||||
if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1))
|
||||
|
||||
if(!active_power_usage || avail(active_power_usage))
|
||||
add_load(active_power_usage)
|
||||
if(surplus() >= active_power_usage && add_load(active_power_usage) >= active_power_usage) //does the laser have enough power to shoot?
|
||||
if(!powered)
|
||||
powered = 1
|
||||
update_icon()
|
||||
@@ -118,13 +120,19 @@
|
||||
return
|
||||
|
||||
src.last_shot = world.time
|
||||
if(src.shot_number < 3)
|
||||
if(src.shot_number < burst_shots)
|
||||
src.fire_delay = 2
|
||||
src.shot_number ++
|
||||
else
|
||||
src.fire_delay = rand(20,100)
|
||||
src.fire_delay = rand(min_burst_delay, max_burst_delay)
|
||||
src.shot_number = 0
|
||||
|
||||
//need to calculate the power per shot as the emitter doesn't fire continuously.
|
||||
var/burst_time = (min_burst_delay + max_burst_delay)/2 + 2*(burst_shots-1)
|
||||
var/power_per_shot = active_power_usage * (burst_time/10) / burst_shots
|
||||
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
|
||||
A.damage = round(power_per_shot/EMITTER_DAMAGE_POWER_TRANSFER)
|
||||
|
||||
playsound(src.loc, 'sound/weapons/emitter.ogg', 25, 1)
|
||||
if(prob(35))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
|
||||
@@ -12,7 +12,7 @@ field_generator power level display
|
||||
-Aygar
|
||||
*/
|
||||
|
||||
#define field_generator_max_power 250
|
||||
#define field_generator_max_power 250000
|
||||
/obj/machinery/field_generator
|
||||
name = "Field Generator"
|
||||
desc = "A large thermal battery that projects a high amount of energy when powered."
|
||||
@@ -25,12 +25,16 @@ field_generator power level display
|
||||
var/Varedit_start = 0
|
||||
var/Varpower = 0
|
||||
var/active = 0
|
||||
var/power = 20 // Current amount of power
|
||||
var/power = 30000 // Current amount of power
|
||||
var/state = 0
|
||||
var/warming_up = 0
|
||||
var/list/obj/machinery/containment_field/fields
|
||||
var/list/obj/machinery/field_generator/connected_gens
|
||||
var/clean_up = 0
|
||||
|
||||
//If keeping field generators powered is hard then increase the emitter active power usage.
|
||||
var/gen_power_draw = 5500 //power needed per generator
|
||||
var/field_power_draw = 2000 //power needed per field object
|
||||
|
||||
|
||||
/obj/machinery/field_generator/update_icon()
|
||||
@@ -167,8 +171,8 @@ field_generator power level display
|
||||
return 0
|
||||
|
||||
/obj/machinery/field_generator/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(Proj.flag != "bullet")
|
||||
power += Proj.damage
|
||||
if(istype(Proj, /obj/item/projectile/beam))
|
||||
power += Proj.damage * EMITTER_DAMAGE_POWER_TRANSFER
|
||||
update_icon()
|
||||
return 0
|
||||
|
||||
@@ -206,51 +210,44 @@ field_generator power level display
|
||||
if(src.power > field_generator_max_power)
|
||||
src.power = field_generator_max_power
|
||||
|
||||
var/power_draw = 2
|
||||
var/power_draw = gen_power_draw
|
||||
for(var/obj/machinery/field_generator/FG in connected_gens)
|
||||
if (!isnull(FG))
|
||||
power_draw += gen_power_draw
|
||||
for (var/obj/machinery/containment_field/F in fields)
|
||||
if (isnull(F))
|
||||
continue
|
||||
power_draw++
|
||||
if(draw_power(round(power_draw/2,1)))
|
||||
if (!isnull(F))
|
||||
power_draw += field_power_draw
|
||||
power_draw /= 2 //because this will be mirrored for both generators
|
||||
if(draw_power(round(power_draw)) >= power_draw)
|
||||
return 1
|
||||
else
|
||||
for(var/mob/M in viewers(src))
|
||||
M.show_message("\red The [src.name] shuts down!")
|
||||
M.show_message("\red \The [src] shuts down!")
|
||||
turn_off()
|
||||
investigate_log("ran out of power and <font color='red'>deactivated</font>","singulo")
|
||||
src.power = 0
|
||||
return 0
|
||||
|
||||
//This could likely be better, it tends to start loopin if you have a complex generator loop setup. Still works well enough to run the engine fields will likely recode the field gens and fields sometime -Mport
|
||||
/obj/machinery/field_generator/proc/draw_power(var/draw = 0, var/failsafe = 0, var/obj/machinery/field_generator/G = null, var/obj/machinery/field_generator/last = null)
|
||||
if(Varpower)
|
||||
return 1
|
||||
if((G && G == src) || (failsafe >= 8))//Loopin, set fail
|
||||
return 0
|
||||
else
|
||||
failsafe++
|
||||
//Tries to draw the needed power from our own power reserve, or connected generators if we can. Returns the amount of power we were able to get.
|
||||
/obj/machinery/field_generator/proc/draw_power(var/draw = 0, var/list/flood_list = list())
|
||||
flood_list += src
|
||||
|
||||
if(src.power >= draw)//We have enough power
|
||||
src.power -= draw
|
||||
return 1
|
||||
else//Need more power
|
||||
draw -= src.power
|
||||
src.power = 0
|
||||
for(var/obj/machinery/field_generator/FG in connected_gens)
|
||||
if(isnull(FG))
|
||||
continue
|
||||
if(FG == last)//We just asked you
|
||||
continue
|
||||
if(G)//Another gen is askin for power and we dont have it
|
||||
if(FG.draw_power(draw,failsafe,G,src))//Can you take the load
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
else//We are askin another for power
|
||||
if(FG.draw_power(draw,failsafe,src,src))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
return draw
|
||||
|
||||
//Need more power
|
||||
var/actual_draw = src.power //already checked that power < draw
|
||||
src.power = 0
|
||||
|
||||
for(var/obj/machinery/field_generator/FG in connected_gens)
|
||||
if (FG in flood_list)
|
||||
continue
|
||||
actual_draw += FG.draw_power(draw - actual_draw, flood_list) //since the flood list reference is shared this actually works.
|
||||
if (actual_draw >= draw)
|
||||
return actual_draw
|
||||
|
||||
return actual_draw
|
||||
|
||||
/obj/machinery/field_generator/proc/start_fields()
|
||||
if(!src.state == 2 || !anchored)
|
||||
|
||||
@@ -6,7 +6,8 @@ proc
|
||||
emit_particle()
|
||||
|
||||
1 power box
|
||||
the only part of this thing that uses power, can hack to mess with the pa/make it better
|
||||
the only part of this thing that uses power, can hack to mess with the pa/make it better.
|
||||
Lies, only the control computer draws power.
|
||||
|
||||
1 fuel chamber
|
||||
contains procs for mixing gas and whatever other fuel it uses
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
density = 1
|
||||
use_power = 0
|
||||
idle_power_usage = 500
|
||||
active_power_usage = 10000
|
||||
active_power_usage = 70000 //70 kW per unit of strength
|
||||
construction_state = 0
|
||||
active = 0
|
||||
dir = 1
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/New()
|
||||
connected_parts = list()
|
||||
active_power_usage = initial(active_power_usage) * (strength + 1)
|
||||
..()
|
||||
|
||||
|
||||
@@ -29,7 +30,7 @@
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/update_state()
|
||||
if(construction_state < 3)
|
||||
use_power = 0
|
||||
update_use_power(0)
|
||||
assembled = 0
|
||||
active = 0
|
||||
for(var/obj/structure/particle_accelerator/part in connected_parts)
|
||||
@@ -39,7 +40,7 @@
|
||||
connected_parts = list()
|
||||
return
|
||||
if(!part_scan())
|
||||
use_power = 1
|
||||
update_use_power(1)
|
||||
active = 0
|
||||
connected_parts = list()
|
||||
|
||||
@@ -87,6 +88,7 @@
|
||||
else if(href_list["scan"])
|
||||
src.part_scan()
|
||||
else if(href_list["strengthup"])
|
||||
var/old_strength = strength
|
||||
strength++
|
||||
if(strength > 2)
|
||||
strength = 2
|
||||
@@ -97,8 +99,13 @@
|
||||
for(var/obj/structure/particle_accelerator/part in connected_parts)
|
||||
part.strength = strength
|
||||
part.update_icon()
|
||||
|
||||
if (strength != old_strength)
|
||||
active_power_usage = initial(active_power_usage) * (strength + 1)
|
||||
use_power(0) //update power usage
|
||||
|
||||
else if(href_list["strengthdown"])
|
||||
var/old_strength = strength
|
||||
strength--
|
||||
if(strength < 0)
|
||||
strength = 0
|
||||
@@ -107,6 +114,10 @@
|
||||
for(var/obj/structure/particle_accelerator/part in connected_parts)
|
||||
part.strength = strength
|
||||
part.update_icon()
|
||||
|
||||
if (strength != old_strength)
|
||||
active_power_usage = initial(active_power_usage) * (strength + 1)
|
||||
use_power(0) //update power usage
|
||||
src.updateDialog()
|
||||
src.update_icon()
|
||||
return
|
||||
@@ -116,9 +127,9 @@
|
||||
..()
|
||||
if(stat & NOPOWER)
|
||||
active = 0
|
||||
use_power = 0
|
||||
update_use_power(0)
|
||||
else if(!stat && construction_state == 3)
|
||||
use_power = 1
|
||||
update_use_power(1)
|
||||
return
|
||||
|
||||
|
||||
@@ -188,13 +199,13 @@
|
||||
/obj/machinery/particle_accelerator/control_box/proc/toggle_power()
|
||||
src.active = !src.active
|
||||
if(src.active)
|
||||
src.use_power = 2
|
||||
update_use_power(2)
|
||||
for(var/obj/structure/particle_accelerator/part in connected_parts)
|
||||
part.strength = src.strength
|
||||
part.powered = 1
|
||||
part.update_icon()
|
||||
else
|
||||
src.use_power = 1
|
||||
update_use_power(1)
|
||||
for(var/obj/structure/particle_accelerator/part in connected_parts)
|
||||
part.strength = null
|
||||
part.powered = 0
|
||||
|
||||
@@ -88,8 +88,8 @@
|
||||
if(charging)
|
||||
if(excess >= 0) // if there's power available, try to charge
|
||||
var/load = min((capacity-charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity
|
||||
load = add_load(load) // add the load to the terminal side network
|
||||
charge += load * SMESRATE // increase the charge
|
||||
add_load(load) // add the load to the terminal side network
|
||||
|
||||
else // if not enough capcity
|
||||
charging = 0 // stop charging
|
||||
@@ -186,7 +186,8 @@
|
||||
|
||||
/obj/machinery/power/smes/add_load(var/amount)
|
||||
if(terminal && terminal.powernet)
|
||||
terminal.powernet.newload += amount
|
||||
return terminal.powernet.draw_power(amount)
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/power/smes/attack_ai(mob/user)
|
||||
|
||||
@@ -488,12 +488,11 @@ var/list/solars_list = list()
|
||||
|
||||
|
||||
/obj/machinery/power/solar_control/power_change()
|
||||
if(powered())
|
||||
stat &= ~NOPOWER
|
||||
..()
|
||||
if(!(stat & NOPOWER))
|
||||
update_icon()
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
stat |= NOPOWER
|
||||
update_icon()
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
anchored = 1
|
||||
density = 1
|
||||
directwired = 1
|
||||
use_power = 0
|
||||
use_power = 0 // doesn't use APC power
|
||||
var/power_usage = 500 //W
|
||||
|
||||
var/sun_angle = 0 // sun angle as set by sun datum
|
||||
|
||||
@@ -73,10 +74,7 @@
|
||||
// make sure we can draw power from the powernet
|
||||
/obj/machinery/power/tracker/process()
|
||||
|
||||
var/avail = surplus()
|
||||
|
||||
if(avail > 500)
|
||||
add_load(500)
|
||||
if(surplus() >= power_usage && add_load(power_usage) >= power_usage)
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= NOPOWER
|
||||
|
||||
@@ -34,11 +34,7 @@
|
||||
nanomanager.update_uis(src) // update all UIs attached to src
|
||||
|
||||
/obj/machinery/chem_dispenser/power_change()
|
||||
if(powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
stat |= NOPOWER
|
||||
..()
|
||||
nanomanager.update_uis(src) // update all UIs attached to src
|
||||
|
||||
/obj/machinery/chem_dispenser/process()
|
||||
@@ -316,13 +312,6 @@
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/machinery/chem_master/power_change()
|
||||
if(powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
stat |= NOPOWER
|
||||
|
||||
/obj/machinery/chem_master/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob)
|
||||
|
||||
if(istype(B, /obj/item/weapon/reagent_containers/glass))
|
||||
@@ -614,18 +603,16 @@
|
||||
|
||||
|
||||
/obj/machinery/computer/pandemic/power_change()
|
||||
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
icon_state = (src.beaker?"mixer1_b":"mixer0_b")
|
||||
|
||||
else if(powered())
|
||||
else if(!(stat & NOPOWER))
|
||||
icon_state = (src.beaker?"mixer1":"mixer0")
|
||||
stat &= ~NOPOWER
|
||||
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = (src.beaker?"mixer1_nopower":"mixer0_nopower")
|
||||
stat |= NOPOWER
|
||||
|
||||
|
||||
/obj/machinery/computer/pandemic/Topic(href, href_list)
|
||||
|
||||
@@ -45,11 +45,9 @@
|
||||
broadcast_request() //This is the device making the initial event request. It needs to broadcast to other devices
|
||||
|
||||
/obj/machinery/keycard_auth/power_change()
|
||||
if(powered(ENVIRON))
|
||||
stat &= ~NOPOWER
|
||||
..()
|
||||
if(stat &NOPOWER)
|
||||
icon_state = "auth_off"
|
||||
else
|
||||
stat |= NOPOWER
|
||||
|
||||
/obj/machinery/keycard_auth/attack_hand(mob/user as mob)
|
||||
if(user.stat || stat & (NOPOWER|BROKEN))
|
||||
|
||||
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
|
||||
@@ -1,59 +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 = 'code/WorkInProgress/Cael_Aislinn/ShieldGen/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 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
|
||||
|
||||
//---------- 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
|
||||
@@ -5,22 +5,18 @@
|
||||
/obj/machinery/shield_capacitor
|
||||
name = "shield capacitor"
|
||||
desc = "Machine that charges a shield generator."
|
||||
icon = 'code/WorkInProgress/Cael_Aislinn/ShieldGen/shielding.dmi'
|
||||
icon = 'icons/obj/machines/shielding.dmi'
|
||||
icon_state = "capacitor"
|
||||
var/active = 1
|
||||
var/active = 0
|
||||
density = 1
|
||||
var/stored_charge = 0
|
||||
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 = 5e6
|
||||
var/charge_limit = 200000
|
||||
var/max_charge = 8e6 //8 MJ
|
||||
var/max_charge_rate = 400000 //400 kW
|
||||
var/locked = 0
|
||||
//
|
||||
use_power = 1 //0 use nothing
|
||||
//1 use idle power
|
||||
//2 use active power
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 100
|
||||
var/charge_rate = 100
|
||||
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()
|
||||
@@ -75,12 +71,12 @@
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/shield_capacitor/attack_hand(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/shield_capacitor/interact(mob/user)
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN)) )
|
||||
if (!istype(user, /mob/living/silicon))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=shield_capacitor")
|
||||
@@ -90,13 +86,13 @@
|
||||
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 += "[time_since_fail > 2 ? "<font color=green>Charging stable.</font>" : "<font color=red>Warning, low charge!</font>"]<br>"
|
||||
t += "Charge: [stored_charge] Watts ([100 * stored_charge/max_charge]%)<br>"
|
||||
t += "Charge rate: \
|
||||
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] Watts/sec \
|
||||
<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> \
|
||||
@@ -109,20 +105,25 @@
|
||||
user.set_machine(src)
|
||||
|
||||
/obj/machinery/shield_capacitor/process()
|
||||
//
|
||||
if(active)
|
||||
use_power = 2
|
||||
if(stored_charge + charge_rate > max_charge)
|
||||
active_power_usage = max_charge - stored_charge
|
||||
else
|
||||
active_power_usage = charge_rate
|
||||
stored_charge += active_power_usage
|
||||
else
|
||||
use_power = 1
|
||||
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 < active_power_usage * 1.5)
|
||||
time_since_fail = 0
|
||||
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[])
|
||||
..()
|
||||
@@ -131,34 +132,20 @@
|
||||
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(active)
|
||||
use_power = 2
|
||||
else
|
||||
use_power = 1
|
||||
if( href_list["charge_rate"] )
|
||||
charge_rate += text2num(href_list["charge_rate"])
|
||||
if(charge_rate > charge_limit)
|
||||
charge_rate = charge_limit
|
||||
else if(charge_rate < 0)
|
||||
charge_rate = 0
|
||||
//
|
||||
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
|
||||
if( powered() )
|
||||
if (src.active)
|
||||
icon_state = "capacitor"
|
||||
else
|
||||
icon_state = "capacitor"
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = "capacitor"
|
||||
stat |= NOPOWER
|
||||
..()
|
||||
|
||||
/obj/machinery/shield_capacitor/verb/rotate()
|
||||
set name = "Rotate capacitor clockwise"
|
||||
@@ -6,30 +6,29 @@
|
||||
//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 = "shield generator"
|
||||
name = "bubble shield generator"
|
||||
desc = "Machine that generates an impenetrable field of energy when activated."
|
||||
icon = 'code/WorkInProgress/Cael_Aislinn/ShieldGen/shielding.dmi'
|
||||
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.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.01 //how many renwicks per watt?
|
||||
//
|
||||
use_power = 1 //0 use nothing
|
||||
//1 use idle power
|
||||
//2 use active power
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 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)
|
||||
@@ -88,12 +87,12 @@
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/shield_gen/attack_hand(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/shield_gen/interact(mob/user)
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN)) )
|
||||
if (!istype(user, /mob/living/silicon))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=shield_generator")
|
||||
@@ -104,29 +103,29 @@
|
||||
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 += "[time_since_fail > 2 ? "<font color=green>Field is stable.</font>" : "<font color=red>Warning, field is unstable!</font>"]<br>"
|
||||
t += "Coverage radius (restart required): \
|
||||
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 * 2]m \
|
||||
[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: [average_field_strength] Renwicks ([target_field_strength ? 100 * average_field_strength / target_field_strength : "NA"]%)<br>"
|
||||
t += "Upkeep energy: [field.len * average_field_strength / energy_conversion_rate] Watts/sec<br>"
|
||||
t += "Charge rate: <a href='?src=\ref[src];strengthen_rate=-0.1'>--</a> \
|
||||
[strengthen_rate] Renwicks/sec \
|
||||
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 += "Additional energy required to charge: [field.len * strengthen_rate / energy_conversion_rate] Watts/sec<br>"
|
||||
t += "Maximum field strength: \
|
||||
<a href='?src=\ref[src];target_field_strength=-100'>\[min\]</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=-10'>--</a> \
|
||||
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] Renwicks \
|
||||
[target_field_strength] Renwick \
|
||||
<a href='?src=\ref[src];target_field_strength=1'>+</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=10'>++</a> \
|
||||
<a href='?src=\ref[src];target_field_strength=100'>\[max\]</a><br>"
|
||||
<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>"
|
||||
@@ -134,34 +133,39 @@
|
||||
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/stored_renwicks = 0
|
||||
var/target_strength_this_update = min(strengthen_rate + max(average_field_strength, 0), target_field_strength)
|
||||
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)
|
||||
|
||||
if(active && owned_capacitor)
|
||||
var/required_energy = field.len * target_strength_this_update / energy_conversion_rate
|
||||
//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)
|
||||
stored_renwicks = assumed_charge * energy_conversion_rate
|
||||
total_renwick_increase = assumed_charge * energy_conversion_rate
|
||||
owned_capacitor.stored_charge -= assumed_charge
|
||||
|
||||
average_field_strength = 0
|
||||
var/renwicks_per_field = 0
|
||||
if(stored_renwicks != 0)
|
||||
renwicks_per_field = stored_renwicks / field.len
|
||||
|
||||
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)
|
||||
if(active && renwicks_per_field > 0)
|
||||
var/amount_to_strengthen = min(renwicks_per_field - E.strength, strengthen_rate)
|
||||
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
|
||||
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(-E.strength)
|
||||
E.Strengthen(amount_to_strengthen)
|
||||
|
||||
average_field_strength += E.strength
|
||||
|
||||
average_field_strength /= field.len
|
||||
if(average_field_strength < 1)
|
||||
@@ -176,87 +180,29 @@
|
||||
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 += text2num(href_list["change_radius"])
|
||||
if(field_radius > 200)
|
||||
field_radius = 200
|
||||
else if(field_radius < 0)
|
||||
field_radius = 0
|
||||
field_radius = between(0, field_radius + text2num(href_list["change_radius"]), max_field_radius)
|
||||
else if( href_list["strengthen_rate"] )
|
||||
strengthen_rate += text2num(href_list["strengthen_rate"])
|
||||
if(strengthen_rate > 1)
|
||||
strengthen_rate = 1
|
||||
else if(strengthen_rate < 0)
|
||||
strengthen_rate = 0
|
||||
strengthen_rate = between(0, strengthen_rate + text2num(href_list["strengthen_rate"]), max_strengthen_rate)
|
||||
else if( href_list["target_field_strength"] )
|
||||
target_field_strength += text2num(href_list["target_field_strength"])
|
||||
if(target_field_strength > 1000)
|
||||
target_field_strength = 1000
|
||||
else if(target_field_strength < 0)
|
||||
target_field_strength = 0
|
||||
//
|
||||
target_field_strength = between(1, target_field_strength + text2num(href_list["target_field_strength"]), max_field_strength)
|
||||
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/shield_gen/power_change()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "broke"
|
||||
else
|
||||
if( powered() )
|
||||
if (src.active)
|
||||
icon_state = "generator1"
|
||||
else
|
||||
icon_state = "generator0"
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = "generator0"
|
||||
stat |= NOPOWER
|
||||
if (src.active)
|
||||
toggle()
|
||||
|
||||
/obj/machinery/shield_gen/ex_act(var/severity)
|
||||
|
||||
if(active)
|
||||
toggle()
|
||||
return ..()
|
||||
|
||||
/*
|
||||
/obj/machinery/shield_gen/proc/check_powered()
|
||||
check_powered = 1
|
||||
if(!anchored)
|
||||
powered = 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)
|
||||
powered = 0
|
||||
return 0
|
||||
var/datum/powernet/PN = powernets[net] // find the powernet. Magic code, voodoo code.
|
||||
|
||||
if(!PN)
|
||||
powered = 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
|
||||
powered = 0
|
||||
return 0
|
||||
else
|
||||
powered = 1
|
||||
if(PN)
|
||||
storedpower += shieldload
|
||||
PN.newload += shieldload //uses powernet power.
|
||||
*/
|
||||
|
||||
/obj/machinery/shield_gen/proc/toggle()
|
||||
set background = 1
|
||||
active = !active
|
||||
power_change()
|
||||
update_icon()
|
||||
if(active)
|
||||
var/list/covered_turfs = get_shielded_turfs()
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -277,10 +223,37 @@
|
||||
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()
|
||||
for(var/turf/T in range(field_radius, src))
|
||||
if(get_dist(src,T) == field_radius)
|
||||
out.Add(T)
|
||||
|
||||
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
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Reference in New Issue
Block a user